diff --git a/CMS_CORE_Library/CMS_CORE_Library.csproj b/CMS_CORE_Library/CMS_CORE_Library.csproj
index b736dbc..d92774a 100644
--- a/CMS_CORE_Library/CMS_CORE_Library.csproj
+++ b/CMS_CORE_Library/CMS_CORE_Library.csproj
@@ -153,6 +153,7 @@
+
diff --git a/CMS_CORE_Library/Models/CmsError.cs b/CMS_CORE_Library/Models/CmsError.cs
index 0bd46d7..290bea2 100644
--- a/CMS_CORE_Library/Models/CmsError.cs
+++ b/CMS_CORE_Library/Models/CmsError.cs
@@ -72,6 +72,7 @@ namespace CMS_CORE_Library.Models
OSAI_TT_FOLDER_NOT_FOUND = 27,
OPTION_NOT_CONSISTENT = 28,
WRONG_CMS_PP = 29,
- SIEMENS_TOOL_TABLE_ERROR = 30
+ SIEMENS_TOOL_TABLE_ERROR = 30,
+ PLC_IP_NOT_FOUND = 31
}
}
\ No newline at end of file
diff --git a/CMS_CORE_Library/Models/DataStructures.cs b/CMS_CORE_Library/Models/DataStructures.cs
index b873ba3..4e6aa2b 100644
--- a/CMS_CORE_Library/Models/DataStructures.cs
+++ b/CMS_CORE_Library/Models/DataStructures.cs
@@ -178,6 +178,7 @@ namespace CMS_CORE_Library.Models
public static CmsError INCORRECT_PARAMETERS_ERROR = new CmsError(CMS_ERROR_CODES.INCORRECT_PARAMETERS, "error_incorrect_parameters");
public static CmsError INCORRECT_LANGUAGE_ERROR = new CmsError(CMS_ERROR_CODES.NC_LANGUAGE_ERROR, "error_invalid_language");
public static CmsError SIEMENS_ENVIRONMENT_NOT_FOUND_ERROR = new CmsError(CMS_ERROR_CODES.SIEMENS_ENVIRONMENT_NOT_FOUND, "error_siemens_enviroment_not_found_error");
+ public static CmsError PLC_IP_NOT_FOUND_ERROR = new CmsError(CMS_ERROR_CODES.PLC_IP_NOT_FOUND, "error_plc_ip_not_found_error");
public static CmsError SIEMENS_HMI_NOT_RUNNING_ERROR = new CmsError(CMS_ERROR_CODES.SIEMENS_HMI_NOT_RUNNING, "error_siemens_hmi_not_running");
public static CmsError MAX_TOOL_REACHED_ERROR = new CmsError(CMS_ERROR_CODES.MAX_TOOL_REACHED, "error_max_tool_reached");
public static CmsError MAX_EDGES_PER_TOOL_REACHED_ERROR = new CmsError(CMS_ERROR_CODES.MAX_EDGES_PER_TOOL_REACHED, "error_max_edges_per_tool_reached");
diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs
new file mode 100644
index 0000000..fd87d24
--- /dev/null
+++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs
@@ -0,0 +1,7071 @@
+using CMS_CORE_Library.Models;
+using Siemens.Sinumerik.Operate.Services;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Windows.Forms;
+using System.Xml.Linq;
+using static CMS_CORE_Library.Models.DataStructures;
+using static CMS_CORE_Library.Nc;
+using static CMS_CORE_Library.Siemens.MEMORY_ADDRESS;
+using static CMS_CORE_Library.ToolConfigurations;
+using static CMS_CORE_Library.Utils.Nc_Utils;
+using static Siemens.Sinumerik.Operate.Services.ToolMngmntSvc;
+
+namespace CMS_CORE_Library.S7Net
+{
+ public class Nc_S7Net : Nc
+ {
+ // Global Constants
+#if false
+ private const string OptionHMINotRunning = "P66";
+
+ private const string HMIDllName = "Wrapper.dll";
+#endif
+
+ private const string NcNotFound = "Missing response";
+ private const string NcNotFound2 = "networking error";
+#if false
+ private const string NcNotFound3 = "Nc not Connected";
+ private const string SinumerikEnvVar = "HMI_INSTALL_DIR";
+#endif
+ private const int IDMinPLCMessage = 700000;
+ private const int IDMaxPLCMessage = 799999;
+ private const int IDMinChannel = 10000;
+ private const int IDMaxChannel = 19999;
+
+#if false
+ // Siemens Path Constants
+ private const string MAX_CHANNEL_NO_PATH = "/Nck/Configuration/maxnumChannels";
+
+ private const string CONF_CHANNEL_NO_PATH = "/Nck/Configuration/numChannels";
+ private const string NC_TYPE_PATH = "/Nck/Configuration/nckType";
+ private const string NC_VERSION_PATH = "/Nck/Configuration/nckVersion";
+ private const string LANGUAGE_PATH = "/Nck/Configuration/anLanguageOnHmi";
+ private const string SERIAL_NO_PATH = "/Nck/State/hwProductSerialNrL";
+ private const string NC_TIME_PATH = "/Nck/State/sysTimeBCD";
+ private const string NC_GENERIC_MODE_PATH = "/Bag/State/opMode";
+ private const string NC_GENERIC_STATE_PATH = "/Channel/State/chanStatus";
+ private const string JOG_INCR_PATH = "/Channel/GeometricAxis/actIncrVal";
+ private const string ADVANCED_JOG_PATH = "/Channel/State/machFunc";
+ private const string RELATIVE_POS_PATH = "/Channel/GeometricAxis/actToolBasPosEN";
+ private const string UNIT_OF_MEASURE = "/Nck/Configuration/basicLengthUnit";
+
+ private const string ACT_PROG_LINES_PATH = "/Channel/ProgramInfo/actPartProgram";
+ private const string ACT_PROG_NAME_PATH = "/Channel/ProgramPointer/progName";
+ private const string MAGAZINE_ACTION_PATH = "DB258.DBB4000";
+
+ // TOOLS
+ private const string NC_TOOL_FILE_PATH = "//NC/ACT.DIR/TO.DIR/TO_INI.INI";
+ private const string LOCALE_TOOL_FILE_PATH = "C:\\CMS\\Active\\TMP\\TO_INI.INI";
+#endif
+
+ // Global Variables
+ private static DateTime Last_Static_Read;
+
+ private ushort TimeoutConn;
+ private static string Cnc_name;
+ private static string Cnc_SftVersion;
+ private static string Cnc_SeriesNum;
+ private static string Cms_MachNumber;
+ private static uint ConfChannelNo;
+ private static uint MaxChannelNo;
+ private static uint SiemensLanguage;
+ private static string UnitOfMeasure;
+
+ // Alarms data
+ private AlarmSvc SiemensAlmSvc = null;
+ private Alarm[] SiemensAlarms;
+
+#if false
+ // Tool table listeners
+ private static ToolMngmntSvc SiemensToolSvc = null;
+
+ private static DataSvc MagazinePositionSvc = null;
+ private static DataSvc MagazineActionsSvc = null;
+
+ private Guid ToolMngmtListGuid = Guid.Empty;
+
+ // Magazine config parameters
+ private static int MAX_TOOL_NUMER;
+
+ private static int MAX_EDGES_PER_TOOL;
+ private static int MAX_TOOLS_PER_FAMILY;
+ private static int MAX_MULTITOOLS_NUMBER;
+ private static int MAX_TOOLS_PER_MULTITOOL;
+ private static int MAX_MULTITOOLS_LOCATIONS;
+
+ private static bool LIFE_OPTION_ACTIVE;
+ private static bool MULTITOOL_OPTION_ACTIVE;
+
+ private const string PLC_MESSAGES_FILE_PATH = "C:\\Program Files (x86)\\Siemens\\MotionControl\\oem\\sinumerik\\hmi\\lng\\";
+ private static readonly string AXES_FILE_PATH = AppDomain.CurrentDomain.BaseDirectory + "\\Config\\axesConfig.xml";
+
+ // axis data
+ private static List AxesData = new List();
+ public static uint multitoolsNumber = 0;
+
+ public static uint MAX_AXES_FOR_PROCESS = 20;
+
+ // File paths
+ public const string BASE_FILE_PATH = "//NC/";
+ public const string NC_FILE_PATH = "MPF.DIR";
+
+ private static DataSvc AxesSvc;
+ private static DataSvc SelectedProcessSvc;
+ private static ushort SelectedProcess = 0;
+
+ private static Dictionary MachineAxesPosition = new Dictionary();
+ private static Dictionary ToGoAxesPosition = new Dictionary();
+ private static Dictionary InterpAxesPosition = new Dictionary();
+ private static Dictionary ProgrammedAxisPosition = new Dictionary();
+#endif
+
+ private bool EnableAlarms;
+ private bool EnableHeaters;
+ private bool EnableModules;
+ private bool EnableParameters;
+ private bool EnableProd;
+
+ private bool EnableAxes;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Contructor & global methods
+
+ ///
+ ///Instantiate The NC-S7Net Class
+ ///
+ ///Send/Recieve timeout connection [mS]
+ public Nc_S7Net(ushort ConnectionTimeOut)
+ {
+ //Setup options
+ this.EnableAlarms = true;
+ this.EnableHeaters = true;
+ this.EnableModules = true;
+ this.EnableParameters = true;
+ this.EnableProd = true;
+
+ this.EnableAxes = false;
+
+ //Setup timeout
+ TimeoutConn = ConnectionTimeOut;
+ // FIXME: modificare in allarme generico bitmap?
+ SiemensAlarms = new Alarm[] { };
+ }
+
+ ///
+ /// Instantiate The NC-Siemens Class
+ ///
+ /// Send/Recieve timeout connection [mS]
+ /// Enable Axes Svc
+ /// Enable Alarms Svc
+ /// Enable Heaters Svc
+ /// Enable Modules Svc
+ /// Enable Parameters Svc
+ /// Enable Prod Svc
+ public Nc_S7Net(ushort ConnectionTimeOut, bool EnableAxes, bool EnableAlarms, bool EnableHeaters, bool EnableModules, bool EnableParameters, bool EnableProd)
+ {
+ //Setup options
+ this.EnableAlarms = EnableAlarms;
+ this.EnableAxes = EnableAxes;
+ this.EnableHeaters = EnableHeaters;
+ this.EnableModules = EnableModules;
+ this.EnableParameters = EnableParameters;
+ this.EnableProd = EnableProd;
+
+ //Setup timeout
+ TimeoutConn = ConnectionTimeOut;
+ SiemensAlarms = new Alarm[] { };
+ }
+
+ public override CmsError NC_Connect()
+ {
+ // Try to get information
+ try
+ {
+ // Check if Siemens Environment is started
+ CmsError cmsError = CheckS7Ping();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Check connection
+ Item item = new Item("DB258.DBX0.0");
+ DataSvc svc = new DataSvc();
+
+ svc.Read(item);
+ Connected = true;
+
+ // InitializeSiemens objects
+ if (this.EnableAxes)
+ {
+ if (AxesSvc == null)
+ AxesSvc = new DataSvc();
+ }
+
+ if (SelectedProcessSvc == null)
+ {
+ SelectedProcessSvc = new DataSvc();
+
+ SelectedProcessSvc.Subscribe(ManageSelectedProcess, new Item[]
+ {
+ new Item() { Path = "DB258.DBX2582.2" },
+ new Item() { Path = "DB258.DBX2586.2" },
+ new Item() { Path = "DB258.DBX2590.2" },
+ new Item() { Path = "DB258.DBX2594.2" },
+ new Item() { Path = "DB258.DBX2598.2" },
+ new Item() { Path = "DB258.DBX2602.2" },
+ });
+ }
+
+ //Setup the alarms (Only managed in this way (Siemens Thread)
+
+ if (this.EnableAlarms)
+ {
+ SiemensAlarms = new Alarm[] { };
+ SiemensAlmSvc = new AlarmSvc(ConvertToSTEPLanguage(SiemensLanguage).ThreeLetterISOLanguageName);
+ SiemensAlmSvc.Subscribe(AlarmsChanged);
+ Infrastructure.SubscribeLanguageChanged(NcLanguageChanged);
+ }
+
+ if (this.EnableTools)
+ {
+ // Setup tooltable listeners
+ if (SiemensToolSvc == null)
+ {
+ SiemensToolSvc = new ToolMngmntSvc(1);
+ ToolMngmtListGuid = SiemensToolSvc.Subscribe(ToolMngmtSvcHandler);
+ SetupToolTableData();
+ }
+
+ // Setup magazine position listener
+ if (MagazinePositionSvc == null)
+ {
+ MagazinePositionSvc = new DataSvc();
+ SetupMagazinePositionListener();
+ }
+
+ // Setup magazine action
+ if (MagazineActionsSvc == null)
+ {
+ MagazineActionsSvc = new DataSvc();
+ SetupMagazineActionListener();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ private void ManageSelectedProcess(Guid guid, Item[] item, DataSvcStatus[] status)
+ {
+ SelectedProcess = 0;
+ // Set selectedProcess
+ for (int i = 0; i < item.Count(); i++)
+ {
+ if (status[i].Ok)
+ {
+ if (Convert.ToBoolean(item[i].Value))
+ SelectedProcess = (ushort)(i + 1);
+ }
+ }
+
+ if (this.EnableAxes)
+ {
+ // Clean listener
+ AxesSvc.UnSubscribe(ManageAxes);
+
+ if (SelectedProcess > 0)
+ {
+ List axesConf = new List();
+
+ AXES_RAxesNames(SelectedProcess, ref AxesData);
+
+ List- axesData = new List
- ();
+ foreach (var conf in AxesData)
+ {
+ // Setup the items to be subscribed
+ // Machine
+ axesData.Add(new Item() { Path = string.Format("/Nck/{0}[u{1},{2}]", "MachineAxis/actToolBasePos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
+ // Programmed
+ axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/cmdProgPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
+ // Interp
+ axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/actToolEdgeCenterPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
+ // Dist to go
+ axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "MachineAxis/toolBaseDistToGo", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
+ }
+
+ if (axesData.Count() > 0)
+ // Subscribe to axis changes
+ AxesSvc.Subscribe(ManageAxes, axesData.ToArray());
+ }
+ }
+ }
+
+ private void ManageAxes(Guid guid, Item[] item, DataSvcStatus[] status)
+ {
+ lock (MachineAxesPosition)
+ {
+ lock (ProgrammedAxisPosition)
+ {
+ lock (InterpAxesPosition)
+ {
+ lock (ToGoAxesPosition)
+ {
+ MachineAxesPosition.Clear();
+ ProgrammedAxisPosition.Clear();
+ InterpAxesPosition.Clear();
+ ToGoAxesPosition.Clear();
+
+ for (int i = 0; i < AxesData.Count(); i++)
+ {
+ if (status[i * 4].Ok)
+ MachineAxesPosition.Add(item[i * 4].SymbolicName, Convert.ToDouble(item[i * 4].Value));
+ if (status[i * 4 + 1].Ok)
+ ProgrammedAxisPosition.Add(item[i * 4 + 1].SymbolicName, Convert.ToDouble(item[i * 4 + 1].Value));
+ if (status[i * 4 + 2].Ok)
+ InterpAxesPosition.Add(item[i * 4 + 2].SymbolicName, Convert.ToDouble(item[i * 4 + 2].Value));
+ if (status[i * 4 + 3].Ok)
+ ToGoAxesPosition.Add(item[i * 4 + 3].SymbolicName, Convert.ToDouble(item[i * 4 + 3].Value));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Disconnect Method
+ public override CmsError NC_Disconnect()
+ {
+ // Set Connected to FALSE and close the sessions
+ Connected = false;
+ if (SiemensToolSvc != null)
+ {
+ SiemensToolSvc.UnSubscribe(ToolMngmtSvcHandler);
+ // SiemensToolSvc.Dispose();
+ }
+ if (MagazinePositionSvc != null)
+ {
+ MagazinePositionSvc.UnSubscribe(MagazinePositionEnabled_OnChange);
+ //MagazinePositionSvc = null;
+ // MagazinePositionSvc.Dispose();
+ }
+ if (MagazineActionsSvc != null)
+ {
+ MagazineActionsSvc.UnSubscribe(MagazineAction_OnChange);
+ //MagazineActionsSvc = null;
+ // MagazineActionsSvc.Dispose();
+ }
+
+ if (this.EnableAxes)
+ {
+ if (AxesSvc != null)
+ AxesSvc.UnSubscribe(ManageAxes);
+ }
+
+ return NO_ERROR;
+ }
+
+ private void SetupToolTableData()
+ {
+ DataSvc dataSvc = new DataSvc();
+ // Read max tool number
+ Item itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_TOOL");
+ dataSvc.Read(itemToRead);
+ MAX_TOOL_NUMER = (int)itemToRead.Value;
+
+ // Read max edge per tool number
+ itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_MAX_CUTTING_EDGE_PERTOOL");
+ dataSvc.Read(itemToRead);
+ MAX_EDGES_PER_TOOL = (int)itemToRead.Value;
+
+ // Read max tools per family
+ itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MAXNUM_REPLACEMENT_TOOLS");
+ dataSvc.Read(itemToRead);
+ MAX_TOOLS_PER_FAMILY = (int)itemToRead.Value;
+
+ // Read max multitools number
+ itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_MULTITOOL");
+ dataSvc.Read(itemToRead);
+ MAX_MULTITOOLS_NUMBER = (int)itemToRead.Value;
+
+ // Read max tools per multitools
+ itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MAX_TOOLS_PER_MULTITOOL");
+ dataSvc.Read(itemToRead);
+ MAX_TOOLS_PER_MULTITOOL = (int)itemToRead.Value;
+ // Read file
+ string[] toolsStrings = ReadToolTableFile();
+
+ // Read max multitools locations
+ itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_MULTITOOL_LOCATIONS");
+ dataSvc.Read(itemToRead);
+ MAX_MULTITOOLS_LOCATIONS = (int)itemToRead.Value;
+
+ // Read Life option
+ //itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_TOOL_MANAGEMENT_MASK");
+ //LIFE_OPTION_ACTIVE = GetBitValue(Convert.ToInt32(itemToRead.Value), 6);
+ // MULTITOOL_OPTION_ACTIVE = GetBitValue(Convert.ToInt32(itemToRead.Value), 10);
+ MULTITOOL_OPTION_ACTIVE = false;
+
+ // Read Life option
+ itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MNS_ACCESS_WRITE_TM_SUPVIS");
+ dataSvc.Read(itemToRead);
+ LIFE_OPTION_ACTIVE = Convert.ToInt32(itemToRead.Value) == 7;
+ // If not active remove fields from config
+ if (!LIFE_OPTION_ACTIVE)
+ RemoveLifeParamsFromConfig();
+
+ // Read file
+ PopulateToolsTableFromFileStrings(toolsStrings);
+
+ Array.Clear(toolsStrings, 0, toolsStrings.Count());
+
+ //// Subscribe to multitools number
+ //DataSvc d = new DataSvc();
+ //Item i = new Item() { Path = "/Tool/MTCatalogue/numMultiTools[u1]" };
+ //d.Subscribe(MultitoolsNumber_OnChange, i);
+ }
+
+ private void SetupMagazinePositionListener()
+ {
+ // Setup magazine positions listener
+ List
- magPosItems = new List
- ();
+ foreach (var position in MagazinePositionsData)
+ {
+ int paramId = ((position.PositionId - 1) * 11) + 5;
+ magPosItems.Add(new Item()
+ {
+ Path = string.Format("/Tool/Magazine/placeData[c{0} , {1}]", position.MagazineId, paramId),
+ SymbolicName = position.MagazineId + "_" + position.PositionId
+ });
+ }
+
+ if (magPosItems.Count > 0)
+ // Subscribe
+ MagazinePositionSvc.Subscribe(MagazinePositionEnabled_OnChange, magPosItems.ToArray());
+ }
+
+ private void SetupMagazineActionListener()
+ {
+ Item magActionsItem = new Item() { Path = MAGAZINE_ACTION_PATH };
+
+ // Setup magazine actions listener
+ MagazineActionsSvc.Subscribe(MagazineAction_OnChange, magActionsItem);
+ }
+
+ private void RemoveLifeParamsFromConfig()
+ {
+ SiemensToolFieldsConfig.RemoveAll(x => x.Category == "life");
+ SiemensEdgesFieldsConfiguration.EdgeConfiguration.RemoveAll(x => x.Category == "life");
+ }
+
+ public override CmsError NC_GetTranslatedPlcMessages(string language, ref Dictionary messages)
+ {
+ string filePath;
+ try
+ {
+ messages = new Dictionary();
+
+ CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(language);
+
+ // Setup the path of NC alarms translations file
+ filePath = PLC_MESSAGES_FILE_PATH + "cmsalarm_" + cultureInfo.ThreeLetterISOLanguageName.ToUpper() + ".ts";
+ if (!File.Exists(filePath))
+ return INCORRECT_LANGUAGE_ERROR;
+
+ // Open file reader
+ XDocument xmlTranslationsFile;
+
+ using (StreamReader oReader = new StreamReader(filePath, Encoding.ASCII))
+ {
+ xmlTranslationsFile = XDocument.Load(oReader);
+ }
+
+ // Read file with LINQ
+ var messagesList = xmlTranslationsFile
+ .Root
+ .Descendants("context")
+ .Elements()
+ .Where(x => x.Name == "message")
+ .Select(x => new
+ {
+ Key = Convert.ToInt32(x.Element("source").Value.Split('/').FirstOrDefault()),
+ Value = x.Element("translation").Value
+ });
+
+ foreach (var message in messagesList)
+ {
+ // If not contain key
+ if (!messages.Keys.Contains(message.Key))
+ messages.Add(message.Key, message.Value);
+ }
+
+ return NO_ERROR;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ }
+
+ public override CmsError NC_GetAvailableLanguages(ref ICollection languages)
+ {
+ try
+ {
+ foreach (string file in Directory.GetFiles(PLC_MESSAGES_FILE_PATH))
+ {
+ if (Path.GetExtension(file) == ".ts")
+ {
+ string fileName = Path.GetFileNameWithoutExtension(file);
+
+ var splittedFileName = fileName.Split('_');
+ if (splittedFileName.Count() == 2)
+ {
+ if (splittedFileName[0].ToLower() == "cmsalarm")
+ {
+ // Get lang from threeletter
+ var lang = GetCultureFromThreeLetter(splittedFileName[1]);
+
+ if (lang != null)
+ languages.Add(lang);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ #endregion Contructor & global methods
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region High level methods
+
+ // Get the processes-count configurated
+ public override CmsError NC_RProcessesNum(ref ushort ProcNumber)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ ProcNumber = (ushort)ConfChannelNo;
+
+ return NO_ERROR;
+ }
+
+ // Get the NC model Name
+ public override CmsError NC_RModelName(ref string ModelName)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ ModelName = Cnc_name;
+
+ return NO_ERROR;
+ }
+
+ // Get the NC Software Version
+ public override CmsError NC_RSoftwareVersion(ref string SWV)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ SWV = Cnc_SftVersion;
+
+ return NO_ERROR;
+ }
+
+ // Get the NC Language
+ public override CmsError NC_RLanguage(ref CultureInfo Language)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ Language = ConvertToSTEPLanguage(SiemensLanguage);
+
+ return NO_ERROR;
+ }
+
+ // Set the NC Language
+ public override CmsError NC_WLanguage(CultureInfo Language)
+ {
+ //CmsError cmsError = CheckConnection();
+ //if (cmsError.IsError())
+ // return cmsError;
+
+ //// Write write the language
+ //Infrastructure.CurrentLanguage = ConvertToNCLanguage(Language);
+
+ return NO_ERROR;
+ }
+
+ // Get the NC Serial number
+ public override CmsError NC_RSerialNumber(ref string serialNumber)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ serialNumber = Cnc_SeriesNum;
+
+ return NO_ERROR;
+ }
+
+ // Get CMS Machine number
+ public override CmsError NC_RMachineNumber(bool hasLetters, ref string MachNumber)
+ {
+ if (!hasLetters)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ MachNumber = Cms_MachNumber;
+ }
+ else
+ {
+ // New method to read machine number
+ List lists = new List();
+ CmsError cmsError = MEM_RWByteList(R, 0, NEW_MATR_MACC.MemType, NEW_MATR_MACC.Address, NEW_MATR_MACC.SubAddress, 0, 4, ref lists);
+ if (cmsError.IsError())
+ return cmsError;
+
+ lists.Reverse();
+
+ MachNumber = Encoding.ASCII.GetString(lists.ToArray());
+ }
+
+ return NO_ERROR;
+ }
+
+ // Get the Date-Time of the NC
+ public override CmsError NC_RDateTime(ref DateTime ActualTime)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Try to get information
+ try
+ {
+ // Setup variables
+ DataSvc Data = LowPriorityDataSvc();
+ Item itemRead = new Item(NC_TIME_PATH);
+
+ // Read Data
+ Data.Read(itemRead);
+
+ // Save Data
+ ActualTime = (DateTime)itemRead.Value;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ // Check if the NC is in running state
+ public override CmsError NC_RIsRunning(ref bool running)
+ {
+ ushort nProcess = 0;
+ // Get the number of processes
+ CmsError cmsError = NC_RProcessesNum(ref nProcess);
+ if (cmsError.IsError())
+ return cmsError;
+
+ ushort i = 1;
+ running = false;
+ do
+ {
+ PROC_STATUS procStatus = PROC_STATUS.IDLE;
+
+ // Read process status
+ cmsError = PROC_RStatus(i, ref procStatus);
+ if (cmsError.IsError())
+ return cmsError;
+
+ if (procStatus == PROC_STATUS.RUN)
+ running = true;
+ i++;
+ } while (!running || i <= nProcess);
+
+ return NO_ERROR;
+ }
+
+ // Get NC unit of measure
+ public override CmsError NC_RUnitOfMeasure(ref string unitOfMeasure)
+ {
+ CmsError cmsError = ReadStaticNCData();
+ if (cmsError.IsError())
+ return cmsError;
+
+ unitOfMeasure = UnitOfMeasure;
+
+ return NO_ERROR;
+ }
+
+ // Get the Nc Active Alarms
+ public override CmsError NC_RActiveAlarms(ref List alarms)
+ {
+ alarms = SiemensAlarms.
+ Where(x => (x.Id < IDMinPLCMessage || x.Id > IDMaxPLCMessage) && (x.Id < IDMinChannel || x.Id > IDMaxChannel))
+ .Select(x =>
+ {
+ uint id = x.Instance == 1 ? (uint)x.Id : Convert.ToUInt32((x.Id & 0xffff) | (x.Instance << 24));
+ return new AlarmModel()
+ {
+ Id = id,
+ Message = x.Message,
+ IsWarning = false,
+ Process = 0,
+ DateTime = x.TimeStamp
+ };
+ })
+ .GroupBy(x => x.Id).Select(x => x.First())
+ .ToList();
+
+ return NO_ERROR;
+ }
+
+ // Set the Nc Active Page of the NC
+ public override CmsError NC_SetScreenVisible(SCREEN_PAGE screen)
+ {
+ //Waiting time
+ int SleepMs = 50;
+ int TotalTimes = 2000 / 50;
+ int ActualTimes = 0;
+
+ string area = ConvertStepToSiemensScreen(screen);
+ if (string.IsNullOrEmpty(area))
+ return INCORRECT_PARAMETERS_ERROR;
+
+ if (Infrastructure.CurrentActiveArea != area)
+ {
+ Infrastructure.SwitchToArea(area);
+ while (Infrastructure.CurrentActiveArea != area)
+ {
+ if (ActualTimes == TotalTimes)
+ return HMI_NOT_RESPONDING_ERROR;
+ Thread.Sleep(SleepMs);
+ ActualTimes++;
+ }
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError NC_WMDICommand(int processId, string mdiString)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+ try
+ {
+ FileSvc fileSvc = new FileSvc();
+ var a = fileSvc.ReadMdaBuffer(1);
+ fileSvc.WriteMdaBuffer(processId, mdiString);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ #endregion High level methods
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region PLC High-level data
+ public override CmsError PLC_RWManageWatchdog()
+ {
+ bool plcWatchdog = false;
+ CmsError cmsError = MEM_RWBoolean(R, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog);
+ if (cmsError.IsError())
+ return cmsError;
+
+ if (plcWatchdog)
+ return PLC_NOT_RUNNING_ERROR;
+
+ plcWatchdog = true;
+ return MEM_RWBoolean(W, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog);
+ }
+
+ public override CmsError PLC_RActiveMessages(ref List alarms)
+ {
+ bool[] statusBits;
+ int i = 0;
+ List readValues = new List();
+ CmsError cmsError;
+ try
+ {
+ alarms.Clear();
+
+ // Read on data from memory
+ cmsError = MEM_RWIntegerList(R, 0,
+ ALARMS_STATUS.MemType,
+ ALARMS_STATUS.Address,
+ ALARMS_STATUS.SubAddress,
+ (ALARMS_STATUS.Size / 4) + (ALARMS_DATA.Size / 2), // statys_bytes / 4 + data_word / 2
+ ref readValues);
+
+ if (cmsError.IsError())
+ return cmsError;
+
+ alarms.Clear();
+
+ //List readValues = new List();
+
+ //// Read on data from memory
+ //CmsError cmsError = MEM_RWIntegerList(R, 0,
+ // ALARMS_STATUS.MemType,
+ // ALARMS_STATUS.Address,
+ // ALARMS_STATUS.SubAddress,
+ // (ALARMS_STATUS.Size + ALARMS_DATA.Size) / 4, // byte / 4
+ // ref readValues);
+
+ //if (cmsError.IsError())
+ // return cmsError;
+
+ // Convert integer array into bit array
+ statusBits = IntToBits(readValues.ToArray());
+
+ for (i = 0; i < ALARMS_STATUS.Size * 8; i++)
+ {
+ // If alarm is active
+ if (statusBits[i])
+ {
+ // Calculate matching alarm byte info address
+ int dataByteAddress = (i * 16) + ALARMS_NUMBER;
+
+ var processList = new List();
+
+ // Get processes on which alarm is active
+ for (int j = dataByteAddress; j < dataByteAddress + 6; j++)
+ {
+ if (statusBits[j])
+ processList.Add(j + 1 - dataByteAddress);
+ }
+ // Add alarm info into active alarms list
+ alarms.Add(new PlcAlarmModel()
+ {
+ Id = (uint)i + 1,
+ IsWarning = statusBits[dataByteAddress + 7],
+ RestorationIsActive = statusBits[dataByteAddress + 6],
+ Process = processList
+ });
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WRestoreMessage(uint id)
+ {
+ // Check id range
+ if (id > ALARMS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Call restore message
+ CmsError cmsError = PLC_WStrobe(ALARM_ACK, ALARM_RESTORATION_STROBE, id);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WRefreshMessage(uint id)
+ {
+ // Check id range
+ if (id > ALARMS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Call restore message
+ CmsError cmsError = PLC_WStrobe(ALARM_ACK, ALARM_REFRESH_STROBE, id);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WRefreshAllMessages()
+ {
+ return PLC_WNcSoftKey(REFRESH_ALL_ALARMS_SFKEY_INDEX);
+ }
+
+ public override CmsError PLC_RPowerOnData(ref PreAndPostPowerOnModel powerOnModel)
+ {
+ int readValue = 0;
+ // Read pre power on and post power on data from memory
+ CmsError cmsError = MEM_RWInteger(R, 0, PRE_POST_POWER_ON.MemType, PRE_POST_POWER_ON.Address, PRE_POST_POWER_ON.SubAddress, ref readValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ bool[] bits = new bool[32];
+
+ // Convert int into to true/false array
+ bits = IntToBits(readValue);
+ // Create adn set pre power on object
+ PrePowerOnModel prePowerOn = new PrePowerOnModel()
+ {
+ PowerOn = new PowerOnDataModel() { Id = 1, Active = bits[0], Clickable = bits[16] }, // id = N, bits = N, Clickable = N + 8 (Second bit)
+ AirPressure = new PowerOnDataModel() { Id = 2, Active = bits[1], Clickable = bits[17] },
+ ProtectionStatus = new PowerOnDataModel() { Id = 3, Active = bits[2], Clickable = bits[18] },
+ EmergencyButtons = new PowerOnDataModel() { Id = 4, Active = bits[3], Clickable = bits[19] },
+ SettingMode = new PowerOnDataModel() { Id = 5, Active = bits[4], Clickable = bits[20] },
+ StartingKey = new PowerOnDataModel() { Id = 6, Active = bits[5], Clickable = bits[21] }
+ };
+
+ // Create and set post power on object
+ PostPowerOnModel postPowerOn = new PostPowerOnModel()
+ {
+ AxisReset = new PowerOnDataModel() { Id = 9, Active = bits[8], Clickable = bits[24] }, // id = N - 8, bits = N, Clickable = N + 8 (Second bit)
+ WaterjetPump = new PowerOnDataModel() { Id = 10, Active = bits[9], Clickable = bits[25] }
+ };
+
+ powerOnModel = new PreAndPostPowerOnModel()
+ {
+ PostPowerOn = postPowerOn,
+ PrePowerOn = prePowerOn
+ };
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WPowerOnData(uint id, bool value)
+ {
+ // Check bit range
+ if (id > 16)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Call restore message
+ CmsError cmsError = PLC_WStrobe(PRE_POST_POWER_ON_ACK, PRE_POST_POWER_ON_CLICKED, id);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RFunctionAccess(ref List functions)
+ {
+ List readValues = new List();
+ int numberOfIntegers = FUNCTION_ACCESS.Size / 4;
+ // Read functions access data from memory
+ CmsError cmsError = MEM_RWIntegerList(R, 0, FUNCTION_ACCESS.MemType, FUNCTION_ACCESS.Address, FUNCTION_ACCESS.SubAddress, numberOfIntegers, ref readValues);
+ if (cmsError.IsError())
+ return cmsError;
+
+ functions = new List();
+ // Convert int into to true/false array
+ bool[] bits = IntToBits(readValues.ToArray());
+ // Convert array into structured data
+ for (int i = 0; i < bits.Count(); i++)
+ {
+ functions.Add(new FunctionalityModel()
+ {
+ Id = (uint)i + 1,
+ IsActive = bits[i]
+ });
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RAxesResetData(ref AxisResetDataModel axisResetData)
+ {
+ byte value = 0;
+ // Read byte from memory
+ CmsError cmsError = MEM_RWByte(R, 0, AXIS_RESET_PROCEDURE.MemType, AXIS_RESET_PROCEDURE.Address, AXIS_RESET_PROCEDURE.SubAddress, 0, ref value);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Check last bit if is active
+ if ((value & 128) == 128)
+ {
+ // Set to 0 last bit( isActive bit x - 128 )
+ // From 0 to 6 bit represents percentage
+ // If higher than 100 then value = 100
+ byte percentage = value - 128 > 100 ? (byte)100 : (byte)(value - 128);
+ axisResetData = new AxisResetDataModel()
+ {
+ IsActive = true,
+ Percentage = percentage
+ };
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RNcSoftKeys(ref List ncSoftKeys)
+ {
+ CmsError cmsError = PLC_RSoftKeys(NC_SOFTKEYS_VALUE, NC_SOFTKEYS_CLICKABLE, ref ncSoftKeys);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RUserSoftKeys(ref List softKeys)
+ {
+ CmsError cmsError = PLC_RSoftKeys(USER_SOFTKEYS_VALUE, USER_SOFTKEYS_CLICKABLE, ref softKeys);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ private CmsError PLC_RSoftKeys(MEMORY_CELL softKeyStatusMemory, MEMORY_CELL softKeysClickableMemory, ref List softKeys)
+ {
+ softKeys = new List();
+ List readValues = new List();
+
+ int memorySizeToRead = (softKeyStatusMemory.Size + softKeysClickableMemory.Size);
+ // Offset between status and clickable data
+ int offset = softKeyStatusMemory.Size * 8;
+
+ // Read on data from memory
+ CmsError cmsError = MEM_RWIntegerList(R, 0,
+ softKeyStatusMemory.MemType,
+ softKeyStatusMemory.Address,
+ softKeyStatusMemory.SubAddress,
+ memorySizeToRead / 4,
+ ref readValues);
+
+ if (cmsError.IsError())
+ return cmsError;
+ // Convert ints into an array of bools
+ bool[] bits = IntToBits(readValues.ToArray());
+
+ // Convert array into structured data
+ for (ushort i = 0; i < bits.Count() / 2; i++)
+ {
+ softKeys.Add(new SoftKeysModel()
+ {
+ Id = (uint)i + 1,
+ Value = bits[i],
+ Active = bits[i + offset]
+ });
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WNcSoftKey(uint id)
+ {
+ // Check id range
+ if (id > NC_SOFTKEYS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Write strobe into memory
+ CmsError cmsError = PLC_WStrobe(NC_SOFT_KEYS_ACK, NC_SOFT_KEYS_CLICKED, id);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WUserSoftKey(uint id)
+ {
+ // Check id range
+ if (id > USER_SOFTKEYS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Write strobe into memory
+ CmsError cmsError = PLC_WStrobe(USER_SOFT_KEYS_ACK, USER_SOFT_KEYS_CLICKED, id);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RHeadsData(List heads, int number)
+ {
+ // Check parameters
+ if (number > MAX_HEADS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+ heads.Clear();
+
+ List readInts = new List();
+ List readValues = new List();
+ List readHours = new List();
+ // Find the size of a single head
+ int headsByte = (HEADS_DATA.Size / MAX_HEADS_NUMBER);
+ double headsInts = Math.Ceiling((double)(headsByte / 4) + 1);
+
+ // Read data for N heads
+ CmsError cmsError = MEM_RWIntegerList(R, 0,
+ HEADS_DATA.MemType,
+ HEADS_DATA.Address,
+ HEADS_DATA.SubAddress,
+ (int)headsInts * number,
+ ref readInts);
+
+ if (cmsError.IsError())
+ return cmsError;
+ // Convert into list of byte
+ readValues = readInts.SelectMany(BitConverter.GetBytes).ToList();
+
+ // Read Worked time heads
+ cmsError = MEM_RWDWordList(R, 0, HEADS_WORKED_TIMES.MemType, HEADS_WORKED_TIMES.Address, HEADS_WORKED_TIMES.SubAddress, number, ref readHours);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Parse and format read data
+ for (int i = 0; i < number; i++)
+ {
+ // Head address = posizion * size of single head in memory
+ var headOffset = i * headsByte;
+ short toolId = SwapShortEndianFormat(BitConverter.ToInt16(readValues.ToArray(), headOffset + 4));
+
+ double residualLife = 0;
+
+ // Find tool
+ var tool = ToolTableData.Where(x => x.Id == toolId).FirstOrDefault();
+
+ // Check if process is selected
+ if (readValues[headOffset] != 0)
+ {
+ try
+ {
+ // Read selected edge
+ Item activeEdgeId = new Item { Path = "/Channel/State/actDNumber[u" + readValues[headOffset] + ",1]" }; // OffsetId
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(activeEdgeId);
+
+ if (Convert.ToInt32(activeEdgeId.Value) != 0)
+ {
+ // Find edge
+ var edge = tool.EdgesData
+ .Where(x => x.Id == Convert.ToInt32(activeEdgeId.Value))
+ .FirstOrDefault();
+ // Set residual life
+ if (edge != null)
+ residualLife = edge.ResidualLife;
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ }
+
+ heads.Add(new HeadDataModel()
+ {
+ Id = (uint)i + 1,
+ Process = readValues[headOffset],
+ Override = readValues[headOffset + 1],
+ Load_Abrasive = SwapShortEndianFormat(BitConverter.ToInt16(readValues.ToArray(), headOffset + 2)), // Uint 16 = 2byte
+ MountedTool_Vacum = toolId, // Uint 16 = 2byte
+ ActualSpeed_Pressure = SwapIntEndianFormat(BitConverter.ToInt32(readValues.ToArray(), headOffset + 6)), // Int32 = 4byte
+ IsActive = (readValues[headOffset + 10] & 1) != 0, // bit 0
+ IsSelected = (readValues[headOffset + 10] & 2) != 0, // bit 1
+ OverrideEditable = (readValues[headOffset + 10] & 4) != 0, // bit 2
+ Configured = (readValues[headOffset + 10] & 8) != 0,
+ Rotation = (readValues[headOffset + 10] & 16) == 0 ? ROTATION.CLOCKWHISE : ROTATION.COUNTERCLOCKWHISE,
+ WorkedTime = readHours[i],
+ Tool = new ToolInSpindleModel()
+ {
+ ChildId = tool == null ? 0 : tool.ChildId,
+ ToolName = tool == null ? "" : tool.FamilyName,
+ Disabled = tool == null ? false : !tool.IsActive,
+ Measured = tool == null ? false : tool.IsMeasured,
+ Broken = tool == null ? false : tool.IsInhibited,
+ MaxLoad = tool == null ? 0 : tool.Load,
+ MaxSpeed = tool == null ? 0 : tool.MaxSpeed,
+ ResidualLife = residualLife
+ }
+ });
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RWorkedTimeHead(int head, ref uint time)
+ {
+ int index = (head - 1) * 4;
+
+ // Read Worked time
+ CmsError cmsError = MEM_RWDWord(R, 0, HEADS_WORKED_TIMES.MemType, HEADS_WORKED_TIMES.Address, HEADS_WORKED_TIMES.SubAddress + index, ref time);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WResetWorkedTimeHead(int head)
+ {
+ byte usControlWord = 0;
+
+ if (head <= 0 || head > MAX_HEADS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Read status
+ CmsError cmsError = MEM_RWByte(R, 0, HEAD_RESET_WORKED_TIME.MemType, HEAD_RESET_WORKED_TIME.Address, HEAD_RESET_WORKED_TIME.SubAddress, 0, ref usControlWord);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Re-Write it status
+ usControlWord = Convert.ToByte((usControlWord & 0xE0) | (head & 0X1F));
+ cmsError = MEM_RWByte(W, 0, HEAD_RESET_WORKED_TIME.MemType, HEAD_RESET_WORKED_TIME.Address, HEAD_RESET_WORKED_TIME.SubAddress, 0, ref usControlWord);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RWorkedTimeMachine(ref uint time)
+ {
+ // Read Worked time
+ CmsError cmsError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WResetWorkedTimeMachine(uint time)
+ {
+ uint actTime = 0;
+
+ // Read actual Value
+ CmsError cmsError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref actTime);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Per richiedere l'azzeramento del timer invio 4 volte il segnale velocemente al PLC
+ // Il PLC resetta il bit e aspetta quello successivo entro 500ms, se no abortisce
+ // Sfrutto così la velocità dei sw, cosa che un "nemico" a mano se provasse a forzare il bit non avrebbe
+ bool bitValue = true;
+ int nTry = 0;
+
+ for (int i = 0; i <= 4; i++)
+ {
+ //Scrivo il bit
+ bitValue = true;
+ nTry = 0;
+ cmsError = MEM_RWBoolean(W, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Aspetto che venga abbassato
+ do
+ {
+ Thread.Sleep(50);
+ nTry += 1;
+ cmsError = MEM_RWBoolean(R, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ } while (bitValue && nTry <= 10);
+
+ //se il valore è rimasto a 1 il plc non l'ha preso in carico, e abortisco
+ if (bitValue)
+ {
+ bitValue = true;
+ cmsError = MEM_RWBoolean(W, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return PLC_NOT_RUNNING_ERROR;
+ }
+ else
+ {
+ //Se l'ha abbassato scrivo il nuovo dato
+ cmsError = MEM_RWDWord(W, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time);
+ }
+
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WHeadOverride(uint id, HEAD_OVERRIDE_SIGN sign)
+ {
+ if (id > MAX_HEADS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ MEMORY_CELL currentStrobeCell = sign == HEAD_OVERRIDE_SIGN.PLUS ? HEADS_STROBE_INCREMENT : HEADS_STROBE_DECREMENT;
+
+ // Write strobe into memory
+ CmsError cmsError = PLC_WStrobe(HEADS_ACK, currentStrobeCell, id);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ // MACHINE COUNTERS
+ public override CmsError PLC_RMachineCounters(ref List counters)
+ {
+ List val = new List();
+ // Read ints
+ CmsError cmsError = MEM_RWDWordList(R, 0, COUNTERS_DATA.MemType, COUNTERS_DATA.Address, COUNTERS_DATA.SubAddress, COUNTERS_DATA.Size / 4, ref val);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Set return value
+ uint i = 0;
+ counters = val.Select(x => new CounterModel()
+ {
+ Id = i++,
+ Value = x
+ })
+ .ToList();
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WResetMachineCounters(uint counter)
+ {
+ bool isResettable = false;
+ CmsError cmsError = MEM_RWBoolean(R, 0, COUNTER_IS_RESETTABLE.MemType, COUNTER_IS_RESETTABLE.Address, COUNTER_IS_RESETTABLE.SubAddress, (int)(counter - 1), ref isResettable);
+ if (cmsError.IsError())
+ return cmsError;
+
+ if (!isResettable)
+ return FUNCTION_NOT_ALLOWED_ERROR;
+
+ cmsError = PLC_WStrobe(COUNTER_IS_RESETTABLE_ACK, COUNTER_IS_RESETTABLE_STROBE, counter);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_ROperatorInputIsNeeded(ref List value)
+ {
+ byte val = 0;
+ // Read memory
+ CmsError cmsError = MEM_RWByte(R, 0, M155_INPUT_NEEDED.MemType, M155_INPUT_NEEDED.Address, M155_INPUT_NEEDED.SubAddress, 0, ref val);
+ if (cmsError.IsError())
+ return cmsError;
+ // Convert byte to an array of bits
+ bool[] bits = ByteToBits(val);
+ uint processId = 1;
+
+ string[] parameters;
+ string actualLine = "";
+
+ foreach (bool bit in bits)
+ {
+ if (bit)
+ {
+ // Read active program line
+ cmsError = PROC_ReadActiveLine(processId, ref actualLine);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Parse line & get parameters
+ parameters = ExtractM155ParametersFromNcCodeLine(actualLine);
+ if (parameters.Count() == 0)
+ {
+ value.Add(new M155InputIsNeededModel()
+ {
+ Process = processId,
+ IsNeeded = bits[processId - 1],
+ Message = "",
+ Type = M155_TYPE.REAL,
+ Buttons = new Dictionary()
+ });
+
+ return NO_ERROR;
+ }
+
+ byte i = 1;
+ if (parameters[0].ToUpper().Trim() == "SHOWVAL")
+ {
+ try
+ {
+ // Skip first parameter because it's the message string
+ // Set button with -> id = 1..5 -> value = parameter value
+ Dictionary buttons = parameters.Skip(2)?.ToDictionary(x => i++, x => x);
+
+ // Read machine variable
+ DataSvc dataSvc = new DataSvc();
+ Item item = new Item()
+ {
+ Path = string.Format("/channel/parameter/r[c{0} , 155]", processId),
+ };
+
+ dataSvc.Read(item);
+
+ value.Add(new M155InputIsNeededModel()
+ {
+ Process = processId,
+ IsNeeded = bits[processId - 1],
+ Message = parameters[1] ?? "",
+ Type = M155_TYPE.SHOW_VAL, // if there aren't buttons is a simple request,
+ Value = Convert.ToDouble(item.Value),
+ Buttons = buttons
+ });
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ }
+ else
+ {
+ // Skip first parameter because it's the message string
+ // Set button with -> id = 1..5 -> value = parameter value
+ Dictionary buttons = parameters.Skip(1)?.ToDictionary(x => i++, x => x);
+
+ value.Add(new M155InputIsNeededModel()
+ {
+ Process = processId,
+ IsNeeded = bit,
+ Message = parameters[0] ?? "",
+ Type = parameters.Count() > 1 ? M155_TYPE.MULTIPLE_BUTTONS : M155_TYPE.REAL, // if there aren't buttons is a simple request
+ Buttons = buttons
+ });
+ }
+ }
+
+ // Next path
+ processId++;
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WOperatorInputResponse(int process, double responseVal)
+ {
+ try
+ {
+ DataSvc dataSvc = new DataSvc();
+ Item item = new Item()
+ {
+ Path = string.Format("/channel/parameter/r[c{0} , 155]", process),
+ Value = responseVal
+ };
+
+ dataSvc.Write(item);
+
+ return PLC_WStrobe(M155_INPUT_ACK, M155_INPUT_STROBE, (uint)process);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ }
+
+ public override CmsError PLC_RM154Data(ref List data, ref bool MTCOnOff)
+ {
+ MTCOnOff = false;
+ CmsError cmsError = MEM_RWBoolean(R, 0, M154_SWITCH_ONOFF.MemType, M154_SWITCH_ONOFF.Address, M154_SWITCH_ONOFF.SubAddress, 1, ref MTCOnOff);
+
+ if (cmsError.IsError())
+ return cmsError;
+
+ byte val = 0;
+ cmsError = MEM_RWByte(R, 0, M154_STROBE.MemType, M154_STROBE.Address, M154_STROBE.SubAddress, 0, ref val);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Convert a byte to an array of booleans
+ bool[] bits = ByteToBits(val);
+ string[] parameters;
+ string tmpStr = "";
+
+ for (uint processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
+ {
+ if (bits[processId - 1])
+ {
+ // Read active program line
+ cmsError = PROC_ReadActiveLine(processId, ref tmpStr);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Parse parameters
+ parameters = ExtractM154ParametersFromNcCodeLine(tmpStr);
+ data.Add(new M154DataModel()
+ {
+ Process = processId,
+ IsNeeded = bits[processId - 1],
+ Parameters = parameters
+ });
+ }
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_W154ManageAck(int processId)
+ {
+ return PLC_ManageActiveAck(M154_STROBE.Address, M154_STROBE.SubAddress, processId - 1, M154_ACK.Address, M154_ACK.SubAddress, processId - 1, M154_STROBE.MemType);
+ }
+
+
+ public override CmsError PLC_RM156Data(ref List value)
+ {
+ byte val = 0;
+ List vals = new List();
+ CmsError cmsError = MEM_RWByte(R, 0, M156_INPUT_NEEDED.MemType, M156_INPUT_NEEDED.Address, M156_INPUT_NEEDED.SubAddress, 0, ref val);
+ if (cmsError.IsError())
+ return cmsError;
+
+ cmsError = MEM_RWByteList(R, 0, M156_INPUT_ID_LIST.MemType, M156_INPUT_ID_LIST.Address, 0, M156_INPUT_ID_LIST.Size, ref vals);
+ if (cmsError.IsError())
+ return cmsError;
+
+ bool[] bits = ByteToBits(val);
+
+ for (int processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
+ {
+ if (bits[processId - 1])
+ {
+ Item item = new Item()
+ {
+ Path = string.Format("/channel/parameter/r[c{0} , 154]", processId),
+ };
+ try
+ {
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(item);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ // Parse line & get parameters
+ value.Add(new M156InputIsNeededModel()
+ {
+ Process = (uint)processId,
+ Id = vals.ElementAt(processId - 1),
+ Value = Convert.ToDouble(item.Value)
+ });
+ }
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WM156Response(int process, double responseVal)
+ {
+ //CmsError cmsError = MEM_RWDouble(W, 0, MEMORY_TYPE.Osai_GD, 900 + (process - 1), ref responseVal);
+ //if (cmsError.IsError())
+ // return cmsError;
+
+ return PLC_WStrobe(M156_INPUT_ACK, M156_INPUT_STROBE, (uint)process);
+ }
+
+ public override CmsError PLC_RScadaValue(string memIndex, SCADA_MEM_TYPE memType, ref object value)
+ {
+ if (memType == SCADA_MEM_TYPE.BOOL)
+ {
+ if (memIndex.ToUpper() == "FALSE")
+ {
+ value = false;
+ return NO_ERROR;
+ }
+ else if (memIndex.ToUpper() == "TRUE")
+ {
+ value = true;
+ return NO_ERROR;
+ }
+ }
+
+ string[] index = memIndex.Split('.');
+ CmsError cmsError = NO_ERROR;
+ try
+ {
+ if (index.Count() == 0 || index.Count() == 1)
+ return INCORRECT_PARAMETERS_ERROR;
+ else if (index.Count() == 2)
+ {
+ if (memType == SCADA_MEM_TYPE.INT)
+ {
+ // read INT
+ int val = 0;
+ cmsError = MEM_RWInteger(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
+
+ value = val;
+ }
+ else if (memType == SCADA_MEM_TYPE.WORD)
+ { // read WORD
+ short val = 0;
+ cmsError = MEM_RWShort(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
+
+ value = val;
+ }
+ else if (memType == SCADA_MEM_TYPE.REAL)
+ { // read DOUBLE
+ double val = 0;
+ cmsError = MEM_RWDouble(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
+
+ value = val;
+ }
+ else
+ { // read BYTE
+ byte val = 0;
+ cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), 0, ref val);
+
+ value = val;
+ }
+ }
+ else if (index.Count() == 3 && memType == SCADA_MEM_TYPE.BOOL)
+ { // read BOOL
+ bool val = false;
+ cmsError = MEM_RWBoolean(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val);
+
+ value = val;
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return cmsError;
+ }
+
+ public override CmsError PLC_RScadaSiemens(ref List objects)
+ {
+ try
+ {
+ List
- items = new List
- ();
+
+ string bit,
+ address;
+ char charType = 'B';
+
+ // Cycle through object
+ for (int i = 0; i < objects.Count(); i++)
+ {
+ // Split memory string -> X.Y.Z
+ string[] splittedMem = objects[i].Address.Split('.');
+ bit = "0";
+ address = "0";
+
+ bool read = true;
+
+ switch (objects[i].MemType)
+ {
+ case SCADA_MEM_TYPE.BOOL:
+ {
+ // Check if memory contains default value
+ if (splittedMem[0].ToUpper() == "FALSE")
+ {
+ objects[i].Value = false;
+ read = false;
+ break;
+ }
+ else if (splittedMem[0].ToUpper() == "TRUE")
+ {
+ objects[i].Value = true;
+ read = false;
+ break;
+ }
+
+ bit = splittedMem[2];
+ address = splittedMem[1];
+ charType = 'X'; // Siemens memory type character
+ }
+ break;
+ case SCADA_MEM_TYPE.BYTE:
+ {
+ address = splittedMem[1];
+ charType = 'B';
+ }
+ break;
+ case SCADA_MEM_TYPE.INT:
+ {
+ address = splittedMem[1];
+ charType = 'D';
+ }
+ break;
+ case SCADA_MEM_TYPE.WORD:
+ {
+ address = splittedMem[1];
+ charType = 'W';
+ }
+ break;
+ case SCADA_MEM_TYPE.REAL:
+ {
+ address = splittedMem[1];
+ charType = 'D';
+ }
+ break;
+ }
+
+ // If needs to read
+ if (read)
+ {
+ // Convert splitted address into Siemens address
+ ConvertMemToPath(MEMORY_TYPE.Siemens_DB,
+ Convert.ToInt32(splittedMem[0]),
+ Convert.ToInt32(address),
+ Convert.ToInt32(bit),
+ 1,
+ charType,
+ out string item);
+
+ // Add to the list of items to be readed
+ items.Add(new Item()
+ {
+ Path = item
+ });
+ }
+ }
+
+ if (items.Count() > 0)
+ {
+ // Read data
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(items.ToArray());
+
+ int alreadyReaded = 0;
+ for (int i = 0; i < objects.Count(); i++)
+ {
+ // Skip the objects already valorised
+ if (objects[i].Value == null)
+ {
+ switch (objects[i].MemType)
+ {
+ case SCADA_MEM_TYPE.BOOL:
+ {
+ // Valorize data
+ objects[i].Value = Convert.ToBoolean(items[i - alreadyReaded].Value);
+ }
+ break;
+ case SCADA_MEM_TYPE.BYTE:
+ {
+ objects[i].Value = Convert.ToByte(items[i - alreadyReaded].Value);
+ }
+ break;
+ case SCADA_MEM_TYPE.INT:
+ {
+ objects[i].Value = Convert.ToInt32(items[i - alreadyReaded].Value);
+ }
+ break;
+ case SCADA_MEM_TYPE.WORD:
+ {
+ objects[i].Value = Convert.ToInt16(items[i - alreadyReaded].Value);
+ }
+ break;
+ case SCADA_MEM_TYPE.REAL:
+ {
+ // Convert value to double
+ var byteVal = BitConverter.GetBytes((uint)items[i - alreadyReaded].Value);
+ var value = unchecked(Convert.ToDouble(BitConverter.ToSingle(byteVal, 0)));
+
+ objects[i].Value = Math.Round(value, objects[i].Round);
+ }
+ break;
+ }
+ }
+ else
+ {
+ // Count items already readed
+ alreadyReaded++;
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value)
+ {
+ string[] index = memIndex.Split('.');
+ CmsError cmsError = NO_ERROR;
+ if (index.Count() == 0)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ else if (index.Count() == 2)
+ {
+ if (memType == SCADA_MEM_TYPE.INT)
+ {
+ // write INT
+ int val = Convert.ToInt32(value);
+ cmsError = MEM_RWInteger(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
+ }
+ else if (memType == SCADA_MEM_TYPE.WORD)
+ { // write WORD
+ short val = Convert.ToInt16(value);
+ cmsError = MEM_RWShort(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
+ }
+ else if (memType == SCADA_MEM_TYPE.REAL)
+ { // write DOUBLE
+ double val = Convert.ToDouble(value);
+ cmsError = MEM_RWDouble(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
+ }
+ else
+ { // write byte
+ byte val = Convert.ToByte(value);
+ cmsError = MEM_RWByte(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), 0, ref val);
+ }
+ }
+ else if (index.Count() == 3 && memType == SCADA_MEM_TYPE.BOOL)
+ { // write BOOL
+ bool val = Convert.ToBoolean(value);
+ cmsError = MEM_RWBoolean(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val);
+ }
+
+ return cmsError;
+ }
+
+ public override CmsError PLC_WAssistedToolingCmd(ushort toolId, ushort familyId, ushort shankId, ushort magazineId, ushort positionId, ASSISTED_TOOLING_ACTION action)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError PLC_RAssistedToolingData(ref AssistedToolingModel data)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError PLC_WTerminateAssistedToolingProcedure()
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ private CmsError PLC_WStrobe(MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id)
+ {
+ CmsError cmsError;
+ bool readValue = false;
+ bool writeValue = true;
+
+ SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId);
+
+ // Check Strobe
+ cmsError = MEM_RWBoolean(R, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // If PLC it's performing another request then return
+ if (readValue)
+ return NO_ERROR;
+
+ // Check ACK
+ cmsError = MEM_RWBoolean(R, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // If PLC it's performing another request then return
+ if (readValue)
+ return NO_ERROR;
+
+ // Write strobe into memory
+ cmsError = MEM_RWBoolean(W, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref writeValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Reset wait ack = 1 and reset the strobe
+ cmsError = ResetStrobe(alarmBitId, strobeByte, ackByte, ackCell.MemType);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ private void SetupAckStrobeAddresses(int ackAddress, int strobeAddress, uint id, out int ackByte, out int strobeByte, out int bit)
+ {
+ ackByte = ackAddress + (((int)id - 1) / 8);
+ strobeByte = strobeAddress + (((int)id - 1) / 8);
+ bit = (((int)id - 1) % 8);
+ }
+
+ private CmsError ResetStrobe(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType)
+ {
+ int n = 600;
+ bool readValue = false;
+ bool writeValue = false;
+ bool ok = false;
+
+ CmsError cmsError;
+ do
+ {
+ // Check ACK
+ cmsError = MEM_RWBoolean(R, 0, memType, TABLE, ackByte, bitId, ref readValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // If true reset strobe
+ if (readValue == true)
+ {
+ // Reset strobe
+ cmsError = MEM_RWBoolean(W, 0, memType, TABLE, strobeByte, bitId, ref writeValue);
+ if (cmsError.IsError())
+ return cmsError;
+ // Exit from cycle
+ n = 0;
+ ok = true;
+ }
+ else
+ {
+ // Decrement
+ n--;
+ // Wait befor next cycle
+ Thread.Sleep(20);
+ }
+ } while (n > 0);
+
+ if (!ok)
+ {
+ // Reset strobe
+ cmsError = MEM_RWBoolean(W, 0, memType, TABLE, strobeByte, bitId, ref writeValue);
+ if (cmsError.IsError())
+ return cmsError;
+ }
+
+ return cmsError;
+ }
+
+ private CmsError PLC_ManageActiveAck(int strobeByte, int strobeSubByte, int strobeBit, int ackByte, int ackSubByte, int ackBit, MEMORY_TYPE memType)
+ {
+ int n = 1200; // 30 seconds
+ bool readValue = false;
+ bool writeValue = true;
+ bool ok = false;
+ // Set ack to 1
+ CmsError cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ do
+ {
+ // Check strobe
+ cmsError = MEM_RWBoolean(R, 0, memType, strobeByte, strobeSubByte, strobeBit, ref readValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // If true reset acknowledge
+ if (!readValue)
+ {
+ writeValue = false;
+ // Reset acknowledge
+ cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
+ if (cmsError.IsError())
+ return cmsError;
+ // Exit from cycle
+ n = 0;
+ ok = true;
+ }
+ else
+ {
+ // Decrement
+ n--;
+ // Wait befor next cycle
+ Thread.Sleep(25);
+ }
+ } while (n > 0);
+
+ // If loop timeout goes in timeout
+ if (!ok)
+ {
+ // Reset acknowledge
+ writeValue = false;
+ cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
+ if (cmsError.IsError())
+ return cmsError;
+ }
+
+ return cmsError;
+ }
+
+ public override CmsError PLC_WExpiredCandy(bool value)
+ {
+ bool newVal = false;
+
+ //Scrivo il dato
+ CmsError cmsError = MEM_RWBoolean(W, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value);
+ if (cmsError.IsError())
+ return cmsError;
+ else
+ {
+ //Leggo il dato
+ cmsError = PLC_RExpiredCandy(ref newVal);
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Se i 2 dati coincidono ritorno OK
+ if (value == newVal)
+ return NO_ERROR;
+ else
+ return PLC_NOT_RUNNING_ERROR;
+
+ }
+ }
+
+ public override CmsError PLC_RExpiredCandy(ref bool value)
+ {
+ CmsError cmsError = MEM_RWBoolean(R, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value);
+ if (cmsError.IsError())
+ return cmsError;
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_WCandy(long value)
+ {
+ // Long is formed by a integer + word
+ // Write Word
+ ushort word = (ushort)((value & 0xFFFF));
+ CmsError cmsError = MEM_RWWord(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word);
+ if (cmsError.IsError())
+ return cmsError;
+
+ int integer = (int)((value & 0xFFFFFFFF0000) >> 16);
+ // Write Integer (+1 is used because osai uses word)
+ cmsError = MEM_RWInteger(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref integer);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Rieggo il dato
+ long newVal = 0;
+ cmsError = PLC_RCandy(ref newVal);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Se i 2 dati coincidono ritorno OK
+ if (value == newVal)
+ return NO_ERROR;
+ else
+ return PLC_NOT_RUNNING_ERROR;
+ }
+
+ public override CmsError PLC_RCandy(ref long value)
+ {
+ // Long is formed by a integer + word
+ // Read word
+ ushort word = 0;
+ CmsError cmsError = MEM_RWWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Read first int
+ uint firtInt = 0;
+ cmsError = MEM_RWDWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref firtInt);
+ if (cmsError.IsError())
+ return cmsError;
+
+
+
+ // Build Long value
+ value = ((long)firtInt << 16) + word;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RActiveClient(ref int clientId)
+ {
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ byte readValues = 0;
+ cmsError = MEM_RWByte(R, 0, ACTIVE_CLIENT.MemType, ACTIVE_CLIENT.Address, ACTIVE_CLIENT.SubAddress, 0, ref readValues);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Convert integer array into bit array
+ bool[] statusBits = ByteToBits(readValues);
+ // check which bit is set
+ for (int i = 0; i < 8; i++)
+ {
+ if (statusBits[i])
+ clientId = i + 1;
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PLC_RToolMovement(ref MovementBetweenMagazinesModel toolMovement)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError PLC_WTerminateMovementProcedure(MOVEMENT_RESPONSE resp)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ #endregion PLC High-level data
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region PROCESS (PATH) High-level data
+
+ // Get the process Mode
+ public override CmsError PROC_RMode(ushort ProcNumber, ref PROC_MODE Mode)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Try to get information
+ try
+ {
+ // Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ Item itemRead = new Item(NC_GENERIC_MODE_PATH + "[u" + ProcNumber + "]");
+ Item itemReadIncr = new Item(JOG_INCR_PATH + "[u" + ProcNumber + "]");
+ Item itemReadAdv = new Item(ADVANCED_JOG_PATH + "[u" + ProcNumber + "]");
+
+ // Read Data
+ Data.Read(itemRead);
+ Data.Read(itemReadIncr);
+ Data.Read(itemReadAdv);
+
+ // Save Data
+ Mode = ConvertToSTEPMode((uint)itemRead.Value, (uint)itemReadIncr.Value, (uint)itemReadAdv.Value);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ // Get the process status
+ public override CmsError PROC_RStatus(ushort ProcNumber, ref PROC_STATUS Status)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Try to get information
+ try
+ {
+ // Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ Item itemRead = new Item(NC_GENERIC_STATE_PATH + "[u" + ProcNumber + "]");
+
+ // Read Data
+ Data.Read(itemRead);
+
+ // Save Data
+ Status = ConvertToSTEPStatus((uint)itemRead.Value);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ // Get PP Lines
+ public override CmsError PROC_RPPLines(ushort ProcNumber, ref List Lines)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ string[] newLines;
+ // Try to get information
+ try
+ {
+ // Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ Item itemRead = new Item(ACT_PROG_LINES_PATH + "[u" + ProcNumber + "]");
+
+ // Read Data
+ Data.Read(itemRead);
+
+ // Save Data
+ newLines = ((string)itemRead.Value).Replace("\r", string.Empty).Split('\n');
+
+ // Setup the return values
+ Lines.Clear();
+ foreach (string Line in newLines)
+ Lines.Add(Line);
+
+ // Remove the first Line (the previous line)
+ if (Lines.Count > 0)
+ Lines.RemoveAt(0);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ // Get PP Name
+ public override CmsError PROC_RSelectedPPName(ushort ProcNumber, ref string Name)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ string RetString;
+ int LastUnderscore;
+
+ // Try to get information
+ try
+ {
+ // Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ Item itemRead = new Item(ACT_PROG_NAME_PATH + "[u" + ProcNumber + "]");
+
+ // Read Data
+ Data.Read(itemRead);
+
+ // Elaborate String
+ RetString = ((string)itemRead.Value);
+ RetString = RetString.Replace("_N_", "");
+ LastUnderscore = RetString.LastIndexOf("_");
+ if (LastUnderscore >= 0)
+ RetString = RetString.Remove(LastUnderscore, 1).Insert(LastUnderscore, ".");
+
+ // Save Data
+ Name = RetString;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ // Get the process Active Alarms
+ public override CmsError PROC_RActiveAlarms(ushort procNumber, ref List alarms)
+ {
+ alarms = SiemensAlarms
+ .Where(x => x.Id >= IDMinChannel && x.Id <= IDMaxChannel && x.Parameters[0].Equals(procNumber.ToString()))
+ .Select(x =>
+ {
+ uint id = x.Instance == 1 ? (uint)x.Id : Convert.ToUInt32((x.Id & 0xffff) | (x.Instance << 24));
+ return new AlarmModel()
+ {
+ Id = id,
+ Message = x.Message,
+ IsWarning = false,
+ Process = procNumber,
+ DateTime = x.TimeStamp
+ };
+ })
+ .ToList();
+
+ return NO_ERROR;
+ }
+
+ // Get process part program data
+ public override CmsError PROC_RStatusAndData(ushort procNumber, ref ProcessDataModel processData)
+ {
+ processData.Id = procNumber;
+ // Read part program name
+ CmsError cmsError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName);
+ if (cmsError.IsError())
+ return cmsError;
+
+ int readValue = 0;
+ // Read processes status from memory
+ cmsError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address, PROCESS_STATUS.SubAddress + ((procNumber - 1) * 2), ref readValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ byte[] bytes = BitConverter.GetBytes(readValue);
+
+ // Convert Byte into true/false array
+ BitArray bits = new BitArray(new byte[] { bytes[0] }); // 1st byte -> 0 : Proccess type (AUX-WORK), 1: Process in alarm status, 2: Run, 3: Hold, 4: Read, 5: PartProgramVisible
+
+ // Get part program info visibility
+ processData.Visible = bits[0];
+
+ // Populate response structure
+ processData.Type = bits[1] ? "WORK" : "AUX";
+ processData.IsSelected = bits[2];
+ processData.IsInAlarm = bits[3];
+ processData.CanLoadProgram = bits[4];
+
+ // Choose process status
+ if (bytes[1] == 1)
+ processData.Status = "HOLD";
+ else
+ {
+ if (bytes[1] == 2)
+ processData.Status = "RUN";
+ else
+ processData.Status = "READY";
+ }
+
+ // Get Reps from 3nd-4th byte
+ processData.Reps = BitConverter.ToUInt16(bytes, 2);
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PROC_RSelectedProcess(ref ushort procNumber)
+ {
+ if (SelectedProcess == 0)
+ return SELECTED_PROCESS_ERROR;
+
+ procNumber = SelectedProcess;
+ //CmsError cmsError;
+ //bool readValue = false;
+
+ //for (int i = 0; i < PROCESS_NUMBER; i++)
+ //{
+ // // Calculate bit address = ProcessBase + processId * 2
+ // int memoryAddress = SELECTED_PROCESS.SubAddress + i * (2);
+ // // Read memory from plc
+ // cmsError = MEM_RWBoolean(R, 0, SELECTED_PROCESS.MemType, SELECTED_PROCESS.Address, memoryAddress, 2, ref readValue);
+ // if (cmsError.IsError())
+ // return cmsError;
+
+ // if (readValue)
+ // {
+ // procNumber = (ushort)(i + 1);
+ // return NO_ERROR;
+ // }
+ //}
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PROC_WSelectProcess(ushort procNumber)
+ {
+ CmsError cmsError;
+ byte processNum = (byte)procNumber;
+
+ // Check parameter
+ if (processNum > MAX_PROCESS_NUMBER)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Write process number
+ cmsError = MEM_RWByte(W, 0, SELECT_PROCESS.MemType, SELECT_PROCESS.Address, SELECT_PROCESS.SubAddress, ref processNum);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError PROC_RSelectedProcessData(int processId, ref SelectedProcessData processData)
+ {
+ if (processId <= 0)
+ return PROC_NOT_FOUND_ERROR;
+
+ try
+ {
+ Item[] items = new Item[7]
+ {
+ new Item { Path = "/Channel/State/actTNumber[u" + processId + ",1]" }, // ActiveToolId
+ new Item { Path = "/Channel/State/actDNumber[u" + processId + ",1]" }, // OffsetId
+ new Item { Path = "/Channel/State/actFrameIndex[u" + processId + "]" }, // Origin
+ new Item { Path = "DB21.DBB4"}, // Work override
+ new Item { Path = "DB21.DBB5"}, // Rapid override,
+ new Item { Path = "/Channel/State/actFeedRateIpo[u" + processId + ", 1]"},
+ new Item { Path = "/Nck/Configuration/numCuttEdgeParams[1]"}, // Cutt Edge Params
+ };
+
+ // Read data
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(items);
+
+ short origin = 0;
+ // Convert SIEMENS enumerable to G(N) format es: G54
+ if (Convert.ToInt16(items[2].Value) > 0)
+ {
+ if (Convert.ToInt16(items[1].Value) >= 5)
+ origin = (short)(Convert.ToInt16(items[2].Value) + 500);
+ else
+ origin = (short)(Convert.ToInt16(items[2].Value) + 53);
+ }
+
+ OffsetModel offset = new OffsetModel();
+
+ //Read the ID of the Tool & Edge
+ short actualToolId = Convert.ToInt16(items[0].Value);
+ short actualEdgeId = Convert.ToInt16(items[1].Value);
+ short numCuttEdgeParams = Convert.ToInt16(items[6].Value);
+ int offsetEdge = (actualEdgeId - 1) * numCuttEdgeParams;
+
+ if (actualToolId != 0 && actualEdgeId != 0)
+ {
+ //Setup the items for the tools. Must be read only this value
+ Item[] itemsToolEdge = new Item[4]
+ {
+ new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 3) + "]" }, // $TC_DP3
+ new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 6) + "]" }, // $TC_DP6
+ new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 12) + "]" }, // $TC_DP12
+ new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 15) + "]" } // $TC_DP15
+ };
+
+ dataSvc.Read(itemsToolEdge);
+
+ offset = new OffsetModel()
+ {
+ Id = actualEdgeId,
+ Length = Convert.ToDouble(itemsToolEdge[0].Value),
+ Radius = Convert.ToDouble(itemsToolEdge[1].Value),
+ WearLength = Convert.ToDouble(itemsToolEdge[2].Value),
+ WearRadius = Convert.ToDouble(itemsToolEdge[3].Value),
+ RealLength = Convert.ToDouble(itemsToolEdge[0].Value) + Convert.ToDouble(itemsToolEdge[2].Value),
+ RealRadius = Convert.ToDouble(itemsToolEdge[1].Value) + Convert.ToDouble(itemsToolEdge[3].Value)
+ };
+
+ /* Other Method. Find it in the Database of the Tools... Too SLow? (Nicola Carminati 08/08/19)
+ // Find edge
+ EdgeModel edge = ToolTableData.Where(x => x.Id == Convert.ToInt16(items[0].Value))
+ .FirstOrDefault()
+ .EdgesData.Where(x => x.Id == Convert.ToInt16(items[1].Value))
+ .FirstOrDefault();
+
+
+ //Find the Type of the Tool
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+ List toolTypeConfig = toolEdgesConfig.EdgesConfig[
+ ToolTableData.Where(x => x.Id == Convert.ToInt16(items[0].Value)).FirstOrDefault().ToolType
+ ];
+
+ if(toolTypeConfig != null && toolTypeConfig.Count > 0)
+ {
+ //Read Names of the parameters
+ String lenghtName = toolTypeConfig.Where(x => x.Path == "$TC_DP3[").FirstOrDefault().Name;
+ String radiusName = toolTypeConfig.Where(x => x.Path == "$TC_DP6[").FirstOrDefault().Name;
+ String wearLenghtName = toolTypeConfig.Where(x => x.Path == "$TC_DP12[").FirstOrDefault().Name;
+ String wearRadiusName = toolTypeConfig.Where(x => x.Path == "$TC_DP15[").FirstOrDefault().Name;
+
+ if(!String.IsNullOrEmpty(wearLenghtName) && !String.IsNullOrEmpty(wearRadiusName) && !String.IsNullOrEmpty(lenghtName) && !String.IsNullOrEmpty(radiusName))
+ {
+ // Convert edgeModel to offsetModel
+ offset = new OffsetModel()
+ {
+ Id = (short)edge.Id,
+ Length = edge.EdgeAdditionalParams[lenghtName],
+ Radius = edge.EdgeAdditionalParams[radiusName],
+ WearLength = edge.EdgeAdditionalParams[wearLenghtName],
+ WearRadius = edge.EdgeAdditionalParams[wearRadiusName],
+ RealLength = edge.EdgeAdditionalParams[lenghtName] + edge.EdgeAdditionalParams[wearLenghtName],
+ RealRadius = edge.EdgeAdditionalParams[radiusName] + edge.EdgeAdditionalParams[wearRadiusName]
+ };
+
+ }
+
+ }*/
+
+ }
+
+ // Creata return model
+ processData = new SelectedProcessData
+ {
+ ActiveOffsetId = Convert.ToInt16(items[1].Value),
+ Origin = origin,
+ ProcessMessage = "",
+ WorkOverride = Convert.ToByte(items[3].Value),
+ RapidOverride = Convert.ToByte(items[4].Value),
+ OffsetData = offset,
+ FeedOverride = Convert.ToDouble(items[5].Value)
+ };
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ private CmsError PROC_ReadActiveLine(uint processId, ref string line)
+ {
+ try
+ {
+ Item item = new Item();
+ if (processId == 0)
+ item.Path = "/Channel/ProgramInfo/actBlock[u1,1]"; // Default
+ else
+ item.Path = "/Channel/ProgramInfo/actBlock[u" + processId + ",1]";
+
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(item);
+
+ line = item.Value.ToString();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ #endregion PROCESS (PATH) High-level data
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region PROCESS-AXES (PATH) High-level data
+
+ public override CmsError AXES_RInterpPosition(ushort channel, ref Dictionary axes)
+ {
+ try
+ {
+ axes = new Dictionary();
+ // Cycle between axes
+ // The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
+ // axes = InterpAxesPosition.ToDictionary(x => x.Key, x => x.Value); This code throws exceptions
+ lock (InterpAxesPosition)
+ {
+ foreach (var axis in InterpAxesPosition.ToList())
+ {
+ axes.Add(axis.Key, axis.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_RMachinePosition(ushort channel, ref Dictionary axes)
+ {
+ try
+ {
+ axes = new Dictionary();
+
+ lock (MachineAxesPosition)
+ {
+ // Cycle between axes
+ // The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
+ foreach (var axis in MachineAxesPosition.ToList())
+ {
+ axes.Add(axis.Key, axis.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_RProgrPosition(ushort channel, ref Dictionary axes)
+ {
+ try
+ {
+ axes = new Dictionary();
+ lock (ProgrammedAxisPosition)
+ {
+ // Cycle between axes
+ // The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
+ foreach (var axis in ProgrammedAxisPosition.ToList())
+ {
+ axes.Add(axis.Key, axis.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_RFollowingError(ushort channel, ref Dictionary axes)
+ {
+ try
+ {
+ axes = new Dictionary();
+ lock (InterpAxesPosition)
+ {
+ // Cycle between axes
+ // The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
+ foreach (var axis in InterpAxesPosition.ToList())
+ {
+ axes.Add(axis.Key, axis.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_RDistanceToGo(ushort channel, ref Dictionary axes)
+ {
+ try
+ {
+ axes = new Dictionary();
+ lock (ToGoAxesPosition)
+ {
+ // Cycle between axes
+ // The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
+ foreach (var axis in ToGoAxesPosition.ToList())
+ {
+ axes.Add(axis.Key, axis.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ return NO_ERROR;
+ }
+
+ private Dictionary AXES_RAxesPos(ushort channel, string positionType)
+ {
+ Dictionary axes = new Dictionary();
+ List axesConf = new List();
+
+ CmsError cmsError = AXES_RAxesNames(channel, ref axesConf);
+
+ List
- items = new List
- ();
+ foreach (var conf in axesConf)
+ {
+ // Setup the items to be readed
+ items.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", positionType, channel, conf.Id) });
+ }
+
+ DataSvc dataSvc = new DataSvc();
+ // Read all the items
+ dataSvc.Read(items.ToArray());
+
+ int i = 0;
+ foreach (var conf in axesConf)
+ {
+ axes.Add(conf.Id.ToString(), Convert.ToDouble(items[i].Value));
+ i++;
+ }
+
+ return axes;
+ }
+
+ public override CmsError AXES_RAxesNames(ushort channel, ref List axesData)
+ {
+ if (!File.Exists(AXES_FILE_PATH))
+ return CmsError.InternalError("File" + AXES_FILE_PATH + " not found", new Exception("File" + AXES_FILE_PATH + " not found"));
+
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+ List configuredAxes = new List();
+
+ Item[] ncAxes = new Item[MAX_AXES_FOR_PROCESS * 3];
+ try
+ {
+ // Check if the static object is already populated
+ if (AxesData.Count == 0)
+ {
+ XDocument xmlAxesFile = XDocument.Load(AXES_FILE_PATH);
+ // Read data from file
+ configuredAxes = xmlAxesFile
+ .Root
+ .Elements()
+ .Select(x => new AxisModel()
+ {
+ Id = Convert.ToInt32(x.Attribute("id").Value),
+ Name = x.Value,
+ IsSelectable = false
+ })
+ .Where(x => x.Id != 0) // Parse only active axes
+ .ToList();
+ }
+
+ // Object used for reading data from NC
+ DataSvc svcData = new DataSvc();
+
+ bool[] axesAreVisible = new bool[MAX_AXES_FOR_PROCESS];
+ // Read from Nc
+ for (int i = 1; i <= MAX_AXES_FOR_PROCESS; i++)
+ {
+ // Set the path to read on which process is the axis
+ ncAxes[i - 1] = new Item("/Nck/MachineAxis/chanNoAxisIsActive[" + i + "]");
+ // Set the path in order to find which axes are visible
+ ncAxes[i - 1 + MAX_AXES_FOR_PROCESS] = new Item("/NC/_N_CH_TEA_ACX/$MC_DISPLAY_AXIS[u" + channel + "," + i + "]");
+ // Set the path of the axes type
+ ncAxes[i - 1 + (MAX_AXES_FOR_PROCESS * 2)] = new Item("/Nck/Configuration/axisType[" + i + "]");
+ }
+
+ svcData.Read(ncAxes);
+
+ for (int i = 0; i < MAX_AXES_FOR_PROCESS; i++)
+ {
+ // Set visible field
+ axesAreVisible[i] = (Convert.ToInt32(ncAxes[i + MAX_AXES_FOR_PROCESS].Value) & 1) == 1;
+ int processAxes = Convert.ToInt32(ncAxes[i].Value);
+ // If axis is visible, add it to the output
+ if (processAxes == channel && axesAreVisible[i])
+ {
+ // Check if axes is configurated axes
+ var axis = configuredAxes.Where(x => x.Id == (i + 1)).FirstOrDefault();
+ if (axis != null)
+ {
+ axis.Type = (AXIS_TYPE)Convert.ToInt32(ncAxes[i + (MAX_AXES_FOR_PROCESS * 2)].Value);
+ AxesData.Add(axis);
+ }
+ }
+ }
+
+ // Get from PLC which axis can be selected
+ List ids = new List();
+ cmsError = MEM_RWByteList(R, 0, AXES_BUTTON_VISIBLE.MemType, AXES_BUTTON_VISIBLE.Address, AXES_BUTTON_VISIBLE.SubAddress, 0, AXES_BUTTON_VISIBLE.Size, ref ids);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Parse the data readed from PLC
+ foreach (byte id in ids)
+ {
+ if (id != 0)
+ {
+ // If axis exists, set it as selectable
+ var tmpAxis = AxesData.Where(x => x.Id == id).FirstOrDefault();
+ if (tmpAxis != null)
+ tmpAxis.IsSelectable = true;
+ }
+ }
+
+ axesData = AxesData;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_RSelectedAxis(ref byte axisId)
+ {
+ // Read byte from memory
+ CmsError cmsError = MEM_RWByte(R, 0, SELECTED_AXIS.MemType, SELECTED_AXIS.Address, SELECTED_AXIS.SubAddress, 1, ref axisId);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_WSelectAxis(byte axisId)
+ {
+ // Write byte from memory
+ CmsError cmsError = MEM_RWByte(W, 0, SELECT_AXIS.MemType, SELECT_AXIS.Address, SELECT_AXIS.SubAddress, 1, ref axisId);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError AXES_ROrigin(int numberOfAxes)
+ {
+ DataSvc dataSvc = new DataSvc();
+ List
- ncAxes = new List
- ();
+
+ List axes = new List();
+ CmsError cmsError = AXES_RAxesNames(1, ref axes);
+
+
+ for (int i = 1; i <= 4; i++)
+ {
+ foreach (var axis in axes)
+ {
+ var num = axis.Id + (axes.Last().Id * i);
+ ncAxes.Add(new Item()
+ {
+ Path = "/Channel/UserFrame/linShift[u1, " + num + "]"
+ });
+ }
+ }
+
+ dataSvc.Read(ncAxes.ToArray());
+
+ return NO_ERROR;
+ }
+
+ #endregion PROCESS-AXES (PATH) High-level data
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region NC Low-level function: single valiable in memory
+
+ //Read-Write a Boolean-Value inside the NC.
+ public override CmsError MEM_RWBoolean(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemBit, ref bool Value)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Check if the Bit Number is Correct
+ cmsError = CheckBitRange(MemBit);
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Try to get information
+ try
+ {
+ //Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+
+ cmsError = ConvertMemToPath(MemType, MemTable, MemIndex, MemBit, 1, 'X', out string itemString);
+ if (cmsError.IsError())
+ return cmsError;
+ Item item = new Item(itemString);
+
+ //Read-Write Data
+ if (bWrite)
+ {
+ item.Value = Value;
+ Data.Write(item);
+ }
+ else
+ {
+ Data.Read(item);
+ Value = (bool)item.Value;
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ //Read-Write a Byte-Value-List inside the NC. In writing-mode the field "Number" is not required
+ public override CmsError MEM_RWByte(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByte, ref byte Value)
+ {
+ List ListValue = new List() { Value };
+
+ //uses the List method with one-element list
+ CmsError cmsError = MEM_RWByteList(bWrite, Process, MemType, MemTable, MemIndex, MemByte, 1, ref ListValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ Value = ListValue.First();
+
+ return NO_ERROR;
+ }
+
+ //Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
+ public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref ushort Value)
+ {
+ List ListValue = new List() { Value };
+
+ //uses the List method with one-element list
+ CmsError cmsError = MEM_RWWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ Value = ListValue.First();
+
+ return NO_ERROR;
+ }
+
+ public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref short Value)
+ {
+ List ListValue = new List() { Value };
+
+ //uses the List method with one-element list
+ CmsError cmsError = MEM_RWShortList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ Value = ListValue.First();
+
+ return NO_ERROR;
+ }
+
+ //Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
+ public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref uint Value)
+ {
+ List ListValue = new List() { Value };
+
+ //uses the List method with one-element list
+ CmsError cmsError = MEM_RWDWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ Value = ListValue.First();
+
+ return NO_ERROR;
+ }
+
+ public override CmsError MEM_RWDouble(bool bWrite, int process, MEMORY_TYPE memType, int memTable, int memIndex, ref double value)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Try to get information
+ try
+ {
+ // Setup variables
+ DataSvc Data = new DataSvc
+ {
+ Timeout = TimeoutConn,
+ PriorityFlag = SlPriority.highPriority
+ };
+
+ cmsError = ConvertMemToPath(memType, memTable, memIndex, 0, 1, 'D', out string itemString);
+ if (cmsError.IsError())
+ return cmsError;
+ Item item = new Item(itemString);
+
+
+ byte[] byteVal;
+
+ // Read-Write Data
+ if (bWrite)
+ {
+ byteVal = BitConverter.GetBytes((Single)value);
+ item.Value = BitConverter.ToUInt32(byteVal, 0);
+ Data.Write(item);
+ }
+ else
+ {
+ Data.Read(item);
+ byteVal = BitConverter.GetBytes((uint)item.Value);
+ value = unchecked(Convert.ToDouble(BitConverter.ToSingle(byteVal, 0)));
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ //Write a Int-Value inside the NC. In writing-mode the field "Number" is not required
+ public override CmsError MEM_RWInteger(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref int Value)
+ {
+ List ListValue = new List() { Value };
+
+ //uses the List method with one-element list
+ CmsError cmsError = MEM_RWIntegerList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
+ if (cmsError.IsError())
+ return cmsError;
+
+ Value = ListValue.First();
+
+ return NO_ERROR;
+ }
+
+ //--------------------------------------------------------------------------------------------------------------------------
+ // Other-NC Version of Memory-Access Methods
+
+ public override CmsError MEM_RWBoolean(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemBit, ref bool Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWByte(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemByte, ref byte Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref uint Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWInteger(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref int Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref short Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref ushort Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWDouble(bool bWrite, int process, MEMORY_TYPE memType, int memIndex, ref double value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemByteStart, int Number, ref List Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ #endregion NC Low-level function: single valiable in memory
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Low level methods
+
+ public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByteStart, int Number, ref List Value)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Try to get/set information
+ try
+ {
+ //Setup variables
+ DataSvc dataSvc = HighPriorityDataSvc();
+
+ cmsError = ConvertMemToPath(MemType, MemTable, MemIndex, 0, (bWrite) ? Value.Count : Number, 'B', out string itemString);
+ if (cmsError.IsError())
+ return cmsError;
+ Item item = new Item(itemString);
+
+ //Read-Write Data
+ if (bWrite)
+ {
+ item.Value = Value.ToArray();
+ dataSvc.Write(item);
+ }
+ else
+ {
+ dataSvc.Read(item);
+ if (item.Value.GetType().IsArray)
+ Value = ((object[])item.Value).Cast().ToList();
+ else
+ {
+ Value.Clear();
+ Value.Add((byte)(uint)item.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Value)
+ {
+ ////Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Try to get/set information
+ try
+ {
+ //Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ cmsError = ConvertMemToPath(MemType, MemTable, MemIndex, 0, (bWrite) ? Value.Count : Number, 'W', out string itemString);
+
+ if (cmsError.IsError())
+ return cmsError;
+ Item item = new Item(itemString);
+
+ //Read-Write Data
+ if (bWrite)
+ {
+ item.Value = Value.ToArray();
+ Data.Write(item);
+ }
+ else
+ {
+ Data.Read(item);
+ if (item.Value.GetType().IsArray)
+ Value = Array.ConvertAll(((object[])item.Value).Cast().ToArray(), input => (ushort)input).ToList();
+ else
+ {
+ Value.Clear();
+ Value.Add(Convert.ToUInt16((uint)item.Value));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Value)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Try to get/set information
+ try
+ {
+ //Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ cmsError = ConvertMemToPath(MemType, MemTable, MemIndex, 0, (bWrite) ? Value.Count : Number, 'W', out string itemString);
+
+ if (cmsError.IsError())
+ return cmsError;
+ Item item = new Item(itemString);
+
+ //Read-Write Data
+ if (bWrite)
+ {
+ item.Value = Value.ToArray();
+ Data.Write(item);
+ }
+ else
+ {
+ Data.Read(item);
+ if (item.Value.GetType().IsArray)
+ Value = Array.ConvertAll(((object[])item.Value).Cast().ToArray(), input => unchecked((short)input)).ToList();
+ else
+ {
+ Value.Clear();
+ Value.Add(unchecked((short)(uint)item.Value));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Value)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Try to get/set information
+ try
+ {
+ //Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ cmsError = ConvertMemToPath(MemType, MemTable, MemIndex, 0, (bWrite) ? Value.Count : Number, 'D', out string itemString);
+
+ if (cmsError.IsError())
+ return cmsError;
+ Item item = new Item(itemString);
+ //Read-Write Data
+ if (bWrite)
+ {
+ item.Value = Value.ToArray();
+ Data.Write(item);
+ }
+ else
+ {
+ Data.Read(item);
+ if (item.Value.GetType().IsArray)
+ Value = ((object[])item.Value).Cast().ToList();
+ else
+ {
+ Value.Clear();
+ Value.Add((uint)item.Value);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Value)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Try to get/set information
+ try
+ {
+ //Setup variables
+ DataSvc Data = HighPriorityDataSvc();
+ cmsError = ConvertMemToPath(MemType, MemTable, MemIndex, 0, (bWrite) ? Value.Count : Number, 'D', out string itemString);
+ if (cmsError.IsError())
+ return cmsError;
+
+ Item item = new Item(itemString);
+
+ //Read-Write Data
+ if (bWrite)
+ {
+ item.Value = Value.ToArray();
+ Data.Write(item);
+ }
+ else
+ {
+ Data.Read(item);
+ if (item.Value.GetType().IsArray)
+ Value = Array.ConvertAll(((object[])item.Value).Cast().ToArray(), input => unchecked((int)input)).ToList();
+ else
+ {
+ Value.Clear();
+ Value.Add(unchecked((int)(uint)item.Value));
+ }
+
+ // Convert BigEndian to LittleEndian
+ Value = ChangeIntListEndianess(Value);
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ #endregion Low level methods
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region NC Low-level function: Parameters
+
+ public override CmsError NC_RParam(short Index, short Bit, ref bool Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError NC_RParam(short Index, ref byte Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError NC_RParam(short Index, ref short Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError NC_RParam(short Index, ref int Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError NC_RParam(short Index, ref double Value)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ #endregion NC Low-level function: Parameters
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region File Management
+
+ public override CmsError FILES_RGetFileList(string path, ref List files)
+ {
+ string[] rootFolders = { "WKS.DIR", "MPF.DIR", "SPF.DIR" };
+ try
+ {
+ string tmpPath = FormatPath(path);
+
+ FileSvc fileSvc = new FileSvc();
+ // Preapare folder node
+ Node folderNode = new Node(BASE_FILE_PATH + tmpPath);
+ // Read files in the folder
+ List nodeArray = fileSvc.List(folderNode).ToList();
+
+ // Go through the array of file nodes
+ foreach (Node element in nodeArray)
+ {
+ PreviewFileModel file = new PreviewFileModel();
+ if (path == "\\\\")
+ {
+ if (rootFolders.Contains(element.Name))
+ {
+ file = new PreviewFileModel()
+ {
+ Path = path + "\\" + element.Name,
+ IsDirectory = element.IsDirNode,
+ Name = GetStringUntilOrEmpty(element.Name, "."),
+ AbsolutePath = element.LogicalPath
+ };
+ files.Add(file);
+ }
+ }
+ else
+ {
+ file = new PreviewFileModel()
+ {
+ Path = path + "\\" + element.Name,
+ IsDirectory = element.IsDirNode,
+ Name = element.IsDirNode ? GetStringUntilOrEmpty(element.Name, ".") : element.Name,
+ AbsolutePath = element.LogicalPath
+ };
+ files.Add(file);
+ }
+
+ // ACCESS LEVEL CHECK (REMOVED TEMPORARILY)
+ //if (element.AccessRights.List == AccessLevel.KEY_0)
+ //{
+ // var file = new PreviewFileModel()
+ // {
+ // Path = path + "\\" + element.Name,
+ // IsDirectory = element.IsDirNode,
+ // Name = element.Name,
+ // AbsolutePath = element.LogicalPath
+ // };
+
+ // files.Add(file);
+ //}
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_RGetFileInfo(string path, ref InfoFile fileInfo)
+ {
+ try
+ {
+ FileSvc fileSvc = new FileSvc();
+ // Preapare folder node
+ Node fileNode = new Node(path);
+
+ if (fileNode != null)
+ {
+ string filePath = "C://CMS//Active//TMP//" + fileNode.Name;
+ FileStream str = new FileStream(filePath, FileMode.Create);
+ CmsError cmsError = FILES_RProgramToFile(path, str);
+ if (cmsError.IsError())
+ return cmsError;
+ fileInfo = new InfoFile()
+ {
+ CreationDate = fileNode.Attributes.LastAccess,
+ LastModDate = fileNode.Attributes.LastAccess,
+ Name = fileNode.Name,
+ Content = File.ReadAllLines(filePath).ToList(),
+ // PreviewBase64 = FindImageBase64String(IMAGES_PATH, fileNode.Name),
+ AbsolutePath = fileNode.LogicalPath
+ };
+
+ str.Close();
+ File.Delete(filePath);
+ }
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_WSetActiveProgram(int processId, string filePath, ref ActiveProgramDataModel data)
+ {
+ try
+ {
+ // string ncPath = FormatPath(filePath);
+
+ FileSvc fileSvc = new FileSvc();
+
+ // Preapare folder node
+ Node selectedNode = new Node(filePath);
+
+ if (!selectedNode.Exists)
+ return FILE_NOT_FOUND_ERROR;
+
+ // Check if file is stored on NC
+ if (filePath.StartsWith(BASE_FILE_PATH))
+ fileSvc.Select(selectedNode, processId);
+ else
+ fileSvc.SelectExtern(selectedNode, processId);
+
+ return FILES_RActiveProgramData(processId, ref data);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ }
+
+ public override CmsError FILES_WDeactivateProgram(int processId)
+ {
+ try
+ {
+ string[] piArgs = new string[4];
+ piArgs[0] = "/NC";
+ piArgs[1] = (200 + processId).ToString();
+ piArgs[2] = "/MPF0";
+ piArgs[3] = "_N_SELECT";
+
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_RActiveProgramData(int processId, ref ActiveProgramDataModel programData)
+ {
+ try
+ {
+ //Setup variables
+ DataSvc dataSvc = new DataSvc();
+
+ // Read position and tool data
+ List
- itemRead = new List
- ()
+ {
+ new Item($"/Channel/ProgramInfo/workPandProgName[u{processId}]"),
+ new Item($"/Channel/ProgramInfo/actPartProgram[u{processId}]")
+ };
+
+ //Read Data
+ dataSvc.Read(itemRead.ToArray());
+
+ // Elaborate String
+ string trimString = ((string)itemRead[0].Value);
+ trimString = trimString.Replace("_N_", "");
+ int lastUnderscore = trimString.LastIndexOf("_");
+ if (lastUnderscore >= 0)
+ trimString = trimString.Remove(lastUnderscore, 1).Insert(lastUnderscore, ".");
+
+ // check if is the NULL Program
+ if (trimString == "/MPF0")
+ {
+ programData = new ActiveProgramDataModel()
+ {
+ Path = "",
+ IsoLines = new List(),
+ TimeLeft = new DateTime()
+ };
+ return NO_ERROR;
+ }
+
+ // Separate string into list of lines
+ List isoLines = itemRead[1]
+ .Value
+ .ToString()
+ .Split('\n') // Line separator
+ .Skip(1) // The actPartProgram read starting with the line before the current
+ .ToList();
+
+ programData = new ActiveProgramDataModel()
+ {
+ Path = trimString,
+ IsoLines = isoLines,
+ TimeLeft = new DateTime()
+ };
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_UploadPartProgram(string localPath, string name, ref string newFilePath)
+ {
+ File.Copy(localPath + name, PART_PRG_PATH + name, true);
+
+ newFilePath = PART_PRG_PATH + name;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_CopyProgram(string partProgramPath, string newPartProgramPath, bool failIfExist)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+ try
+ {
+ //Setup variables
+ FileSvc FileData = new FileSvc();
+ Node sourceNode = new Node(partProgramPath);
+ Node destNode = new Node(newPartProgramPath);
+
+ //Execute Function
+ FileData.Copy(sourceNode, destNode, failIfExist);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_DeleteProgram(string partProgramPath, string partProgramName)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ // Setup variables
+ FileSvc FileData = new FileSvc();
+ Node sourceNode = new Node(partProgramPath);
+
+ //Execute Function
+ FileData.Delete(sourceNode);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_RProgramToFile(string partProgramPath, FileStream localFile)
+ {
+ // Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ // Setup variables
+ string tmpFile = Path.GetTempFileName();
+ FileSvc FileData = new FileSvc();
+ Node sourceNode = new Node(partProgramPath);
+ Node destNode = new Node(tmpFile);
+
+ // Execute Function
+ FileData.Copy(sourceNode, destNode, true);
+
+ FileStream tmpFileStream = new FileStream(tmpFile, FileMode.Open);
+
+ // Write to local file
+ WriteLocalFile(ReadLocalFile(tmpFileStream), ref localFile);
+
+ tmpFileStream.Close();
+ // Delete temporary file
+ File.Delete(tmpFile);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_WProgramFromFile(string partProgramPath, FileStream localFile)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ // Setup variables
+ FileSvc FileData = new FileSvc();
+ Node sourceNode = new Node(localFile.Name);
+ Node destNode = new Node(partProgramPath);
+
+ //Execute Function
+ FileData.Copy(sourceNode, destNode, true);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_RQueueData(ref List statusList)
+ {
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_RQueueDataByProcess(ref QueueStatusModel status, int processId)
+ { return NO_ERROR; }
+
+ public override CmsError FILES_WStartQueue()
+ {
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_WStopQueue()
+ {
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_WLoadNextPartProgram(string localPath, string ncFileName)
+ {
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_WUploadJobFilesAndActivate(int processId, string jobExtractedPath, string fileToActivate)
+ {
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_RGetProgramType(ref PROGRAM_TYPE_ENUM programType)
+ {
+ programType = PROGRAM_TYPE_ENUM.PART_PROGRAM;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError FILES_WCleanUploadFolder()
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError FILES_WUploadCustomMainProgramAndActivate(int processId, string customPartProgramContent, ref ActiveProgramDataModel activeData)
+ {
+ string customMainName = string.Format(CUSTOM_MAIN_PROGRAM, processId);
+
+ string newFilePath = "";
+ CmsError cmsError = FILES_UploadPartProgram(customPartProgramContent, customMainName, ref newFilePath);
+ if (cmsError.IsError())
+ return cmsError;
+
+ cmsError = FILES_WSetActiveProgram(processId, newFilePath, ref activeData);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ private IEnumerable GetLinesFromString(string text)
+ {
+ string line;
+ using (StringReader reader = new StringReader(text))
+ {
+ while ((line = reader.ReadLine()) != null)
+ {
+ yield return line;
+ }
+ }
+ }
+
+ private string FormatPath(string path)
+ {
+ path = path.TrimStart('\\');
+ path = path.TrimStart('/');
+ path = path.TrimEnd('\\');
+
+ return path.Replace('\\', '/');
+ }
+
+ #endregion File Management
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Siemens Tool Management
+
+ public override CmsError TOOLS_RConfiguration(ref ToolTableConfiguration config)
+ {
+ // Set limits
+ config.MaxTools = MAX_TOOL_NUMER;
+ config.MaxEdgesPerTools = MAX_EDGES_PER_TOOL;
+ config.MaxToolsPerFamily = MAX_TOOLS_PER_FAMILY;
+ config.MaxMultitools = MAX_MULTITOOLS_NUMBER;
+ config.MaxToolsPerMultitools = MAX_TOOLS_PER_MULTITOOL;
+
+ // Set options
+ config.MultitoolOptionActive = MULTITOOL_OPTION_ACTIVE;
+ config.FamilyOptionActive = true;
+ config.MagPositionOptionActive = true;
+ config.RadiusMetricType = false;
+ config.LifeOption = true;
+
+ // Set fields configurations
+ config.ToolsConfiguration = SiemensToolFieldsConfig;
+ config.FamiliesConfiguration = SiemensFamilyFieldsConfig;
+ config.ShanksConfiguration = SiemensShankFieldsConfig;
+ config.MagazinePosConfiguration = SiemensMagazinePosFieldsConfig;
+ config.EdgesConfiguration = SiemensEdgesFieldsConfiguration;
+
+ config.EdgesConfiguration.EdgesAdditionalParamsConfiguration = new Dictionary>();
+ // Remove path and set only names as additionalParams
+ foreach (int key in Add_Edges_Param_Config.EdgesConfig.Keys)
+ {
+ List tmpNames = new List();
+ foreach (var conf in Add_Edges_Param_Config.EdgesConfig[key])
+ {
+ tmpNames.Add(conf.Name);
+ }
+ // Set config field
+ config.EdgesConfiguration.EdgesAdditionalParamsConfiguration.Add(key, tmpNames);
+ }
+
+ config.Magazines = MagazineConfig;
+ //config.Magazines = new List();
+ //foreach (PositionModel pos in MagazinePositionsData)
+ //{
+ // var tmp = config.Magazines.Where(x => x.Id == pos.MagazineId).FirstOrDefault();
+ // if (tmp == null)
+ // {
+ // config.Magazines.Add(new MagazineConfigModel()
+ // {
+ // Id = pos.MagazineId,
+ // Type = MAGAZINE_TYPE.CHAIN
+ // });
+ // }
+ //}
+
+ return NO_ERROR;
+ }
+
+ #region Tools functions
+
+ public override CmsError TOOLS_RToolsData(ref List toolTable)
+ {
+ toolTable = new List(ToolTableData.Select(x =>
+ {
+ // Find if is loaded in magazine
+ MountedToolModel tool = MagazineMountedTools.Where(y => y.ToolId == x.Id).FirstOrDefault();
+ if (tool != null)
+ {
+ x.MagazineId = tool.MagazineId;
+ x.PositionId = tool.PositionId;
+ }
+ else
+ {
+ x.MagazineId = 0;
+ x.PositionId = 0;
+ }
+
+ // Update multitool id
+ x.MultitoolId = ToolIsInMultitool(x.Id);
+ return x;
+ })
+ .ToList());
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WAddTool(ref SiemensToolModel tool)
+ {
+ CmsError cmsError = CheckToolData(ref tool);
+ if (cmsError.IsError())
+ return cmsError;
+ try
+ {
+ //Create Tools
+ string[] piArgs = new string[6];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = tool.FamilyName.Trim().PadRight(32); //Name (32 char)
+ piArgs[3] = "00000"; //Tool ID (00000 > autom)
+ piArgs[4] = "00000"; //Duplo ID (00000 > autom)
+ piArgs[5] = "_N_TMCRTO";
+
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+
+ // Get new tool id
+ tool.Id = GetLastToolId();
+
+ // Update new tool
+ cmsError = TOOLS_WUpdateTool(ref tool);
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Get edge additional data
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+ List toolTypeConfig = toolEdgesConfig.EdgesConfig[tool.ToolType];
+ Dictionary edgeData = toolTypeConfig.ToDictionary(x => x.Name, x => 0.0);
+ // Create new edge
+ tool.EdgesData = new List()
+ {
+ new EdgeModel
+ {
+ Id = 1,
+ ResidualLife = 0,
+ PreAlmLife = 0,
+ NominalLife = 0,
+ EdgeAdditionalParams = edgeData
+ }
+ };
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateTool(ref SiemensToolModel tool)
+ {
+ CmsError cmsError = CheckToolData(ref tool);
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ // TC_TP2
+ DataSvc dataSvc = new DataSvc();
+ // Create status byte from bit array
+ BitArray bitArray = new BitArray(new bool[] { tool.IsActive, tool.IsEnabled, tool.IsInhibited, tool.IsMeasured, tool.PreAlarm, tool.InChangeTool, tool.InFixedPlace, tool.IsInUse });
+ int[] array = new int[1];
+ bitArray.CopyTo(array, 0);
+
+ // Read tool info ( rotation, cooling etc...)
+ Item toolInfo = new Item("/Tool/Compensation/edgeData[c" + tool.Id + ",25]");
+ dataSvc.Read(toolInfo);
+ int val = Convert.ToInt32(toolInfo.Value);
+
+ bool clockwhise = false, counterClockwhise = false;
+
+ // Convert rotation into boolean
+ switch (tool.Rotation)
+ {
+ case ROTATION.CLOCKWHISE:
+ clockwhise = true;
+ counterClockwhise = false;
+ break;
+
+ case ROTATION.COUNTERCLOCKWHISE:
+ clockwhise = false;
+ counterClockwhise = true;
+ break;
+ }
+
+ // Set rotation data
+ val = SetBitValue(val, clockwhise, 9);
+ val = SetBitValue(val, counterClockwhise, 10);
+ // Set cooling
+ val = SetBitValue(val, tool.Cooling1, 11);
+ val = SetBitValue(val, tool.Cooling2, 12);
+
+ toolInfo.Value = val;
+
+ List
- items = new List
- ()
+ {
+ // TC_TP2
+ new Item("/Tool/Data/toolIdent[" + tool.Id + "]") { Value = tool.FamilyName },
+ // TC_TP3
+ new Item() { Path = "/Tool/Data/toolsize_left[" + tool.Id + "]", Value = tool.LeftSize },
+ // TC_TP4
+ new Item() { Path = "/Tool/Data/toolsize_right[" + tool.Id + "]", Value = tool.RightSize },
+ // TC_TP7
+ new Item() { Path = "/Tool/Data/toolplace_spec[" + tool.Id + "]", Value = tool.MagazinePositionType },
+ // TC_TP8
+ new Item() { Path = "/Tool/Data/toolStateL[" + tool.Id + "]", Value = array[0] },
+ // TC_DP1
+ new Item() { Path = "/Tool/Compensation/edgeData[c" + tool.Id + ",1]", Value = tool.ToolType },
+ // TC_DP25
+ { toolInfo },
+ // Max speed
+ new Item() { Path = "/Tool/Data/toolMaxVelo[" + tool.Id + "]", Value = tool.MaxSpeed },
+ // Max acceleration
+ // new Item() { Path = "/Tool/Data/toolMaxAcc[" + tool.Id + "]", Value = tool.MaxAcceleration },
+
+ // Custom fields
+ new Item() {Path = "/Tool/User/data[c1," + tool.Id + "]", Value = tool.Load},
+
+ new Item() {Path = "/Tool/User/data[c2," + tool.Id + "]", Value = tool.Gamma},
+
+ new Item() {Path = "/Tool/User/data[c3," + tool.Id + "]", Value = tool.MaxLoadPctAutoload},
+
+ new Item() {Path = "/Tool/User/data[c4," + tool.Id + "]", Value = tool.MinLoadPctAutoload},
+
+ new Item() {Path = "/Tool/User/data[c5," + tool.Id + "]", Value = tool.ToolTypeCode},
+ };
+
+ if (LIFE_OPTION_ACTIVE) // TC_TP9
+ items.Add(new Item() { Path = "/Tool/Data/toolMon[" + tool.Id + "]", Value = (int)tool.LifeType });
+
+ dataSvc.Write(items.ToArray());
+
+ Item childId = new Item() { Path = "/Tool/Data/duploNo[" + tool.Id + "]" };
+ dataSvc.Read(childId);
+ tool.ChildId = Convert.ToInt32(childId.Value);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WDeleteTool(int id)
+ {
+ // Find if tool exists
+ var tool = ToolTableData.Where(x => x.Id == id).FirstOrDefault();
+ if (tool == null)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Check if tool is mounted in magazine
+ bool isMounted = MagazineMountedTools.Exists(x => x.ToolId == tool.Id);
+ if (isMounted)
+ return TOOL_IS_MOUNTED_ERROR;
+
+ try
+ {
+ // Create string parameters
+ string[] piArgs = new string[4];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = id.ToString().PadLeft(5, '0'); // Tool ID (> 00000)
+ piArgs[3] = "_N_DELETO";
+ // Start NC delete command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ private CmsError CheckToolData(ref SiemensToolModel tool)
+ {
+ int toolId = tool.Id;
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Check if it can be added a tool
+ if (ToolTableData.Count == MAX_TOOL_NUMER)
+ return MAX_TOOL_REACHED_ERROR;
+ // Check if family has reached max tool number
+ string family = tool.FamilyName;
+ int toolsWithSameFamily = ToolTableData.Where(x => x.FamilyName == family && x.Id != toolId).Count();
+ if (toolsWithSameFamily >= MAX_TOOLS_PER_FAMILY)
+ return MAX_FAMILY_REACHED_ERROR;
+
+ if (tool.FamilyName.Count() > 32)
+ tool.FamilyName = tool.FamilyName.Substring(0, 32);
+
+ return NO_ERROR;
+ }
+
+ #endregion Tools functions
+
+ #region Shanks functions
+
+ public override CmsError TOOLS_RShanksData(ref List shanksData)
+ {
+ return NO_ERROR;
+ // *SHANK FIX*
+ shanksData = MultitoolsData;
+
+ foreach (ShankModel shank in shanksData)
+ {
+ // Get magazine and position id
+ MountedToolModel mountedTool = MagazineMountedTools.Where(y => y.ToolId == shank.Id).FirstOrDefault();
+ if (mountedTool != null)
+ {
+ shank.MagazineId = mountedTool.MagazineId;
+ shank.PositionId = mountedTool.PositionId;
+ }
+ else
+ {
+ shank.MagazineId = 0;
+ shank.PositionId = 0;
+ }
+
+ // Populate childs
+ foreach (ShankChildModel child in shank.ChildsTools)
+ {
+ // Find tool by id
+ SiemensToolModel tool = ToolTableData.Where(x => x.Id == child.Id).FirstOrDefault();
+ if (tool != null)
+ {
+ child.FamilyName = tool.FamilyName;
+ child.ToolType = tool.ToolType;
+ }
+ }
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WAddShank(ref ShankModel shank)
+ {
+ return NO_ERROR;
+
+ // Check if you can add a multitool
+ if (MultitoolsData.Count >= MAX_MULTITOOLS_NUMBER)
+ return MAX_MULTITOOL_REACHED_ERROR;
+
+ // Check data
+ CmsError cmsError = CheckMultitoolData(ref shank, false);
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ //Create Shank with NC Pi service
+ string[] piArgs = new string[8];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = shank.Name.Trim().PadRight(32);
+ piArgs[3] = "-0001"; // Reserved
+ piArgs[4] = "00000"; // "00000" or “-0001” -> Nc choice / “00001” not allowed
+ piArgs[5] = MAX_TOOLS_PER_MULTITOOL.ToString().PadLeft(3, '0');// shank.MaxChilds.ToString().PadLeft(3, '0'); // From "002" to "$MN_MAX_TOOLS_PER_MULTITOOL" // 001 not allowed
+ piArgs[6] = "1"; // “1”..”3” tipo di riconoscimento distanza tra utensili nel multitool
+ piArgs[7] = "_N_TMCRMT";
+
+ // PI create command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+
+ // Find new tool id
+ shank.Id = GetLastMultitoolId();
+
+ DataSvc dataSvc = new DataSvc();
+
+ // WriteMultitool position type = 0 in order to load tools
+ for (int i = 0; i < MAX_TOOLS_PER_MULTITOOL; i++)
+ {
+ int paramId = (i * 6) + 3;
+
+ Item item = new Item()
+ {
+ Path = string.Format("/Tool/MTPlace/mtPlaceData[c{0},{1}]", shank.Id, paramId),
+ Value = 0
+ };
+ dataSvc.Write(item);
+ }
+ // Update data
+ cmsError = TOOLS_WUpdateShank(ref shank);
+ if (cmsError.IsError())
+ return cmsError;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateShank(ref ShankModel shank)
+ {
+ return NO_ERROR;
+
+ CmsError cmsError = CheckMultitoolData(ref shank, true);
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ DataSvc dataSvc = new DataSvc();
+ // Set status byte
+ BitArray bitArray = new BitArray(new bool[] { false, shank.IsEnabled, shank.IsInhibited, false, false, shank.InChangeTool, shank.InFixedPlace, shank.InUse });
+ int[] array = new int[1];
+ bitArray.CopyTo(array, 0);
+
+ List
- items = new List
- ()
+ {
+ // TC_MTP2
+ new Item("/Tool/MT/multitoolIdent[" + shank.Id + "]") { Value = shank.Name },
+ // TC_MTP3
+ new Item() { Path = "/Tool/MT/multitoolsize_left[" + shank.Id + "]", Value = shank.LeftSize <= 0 ? 1 : shank.LeftSize },
+ // TC_MTP4
+ new Item() { Path = "/Tool/MT/multitoolsize_right[" + shank.Id + "]", Value = shank.RightSize <= 0 ? 1 : shank.RightSize },
+ // TC_TMP7
+ new Item() { Path = "/Tool/MT/multitoolplace_spec[" + shank.Id + "]", Value = shank.MagazinePositionType <= 0 ? 1 : shank.MagazinePositionType },
+ // TC_MTP8
+ new Item() { Path = "/Tool/MT/multitoolStateL[" + shank.Id + "]", Value = array[0] }
+ };
+
+ dataSvc.Write(items.ToArray());
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WDeleteShank(int id)
+ {
+ return NO_ERROR;
+
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Find if exists
+ var multitool = MultitoolsData.Where(x => x.Id == id).FirstOrDefault();
+ if (multitool == null)
+ return INCORRECT_PARAMETERS_ERROR;
+ // Check if multitool is mounted in magazine
+ bool isMounted = MagazineMountedTools.Exists(x => x.ToolId == multitool.Id);
+ if (isMounted)
+ return TOOL_IS_MOUNTED_ERROR;
+ try
+ {
+ // Create string parameters
+ string[] piArgs = new string[7];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = "".PadRight(32);
+ piArgs[3] = "00000";
+ piArgs[4] = id.ToString().PadLeft(5, '0'); // Tool ID (> 00000)
+ piArgs[5] = "1"; // 0 No delete childs, 1 delete childs
+ piArgs[6] = "_N_TMDLMT";
+ // Start NC delete command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ #endregion Shanks functions
+
+ #region Families functions
+
+ public override CmsError TOOLS_RFamilyData(ref List families)
+ {
+ families = FamiliesData;
+ foreach (FamilyModel family in families)
+ {
+ // Get family childs tools
+ family.ChildTools = ToolTableData
+ .Where(x => x.FamilyName == family.Name)
+ .Select(x => new FamilyChildModel()
+ {
+ Id = x.Id,
+ ChildId = x.ChildId,
+ ToolType = x.ToolType
+ })
+ .ToList();
+ // Set current family child tools
+ family.ChildTools
+ .Sort((p, q) => p.ChildId.CompareTo(q.ChildId));
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WAddFamily(ref FamilyModel family)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateFamilyData(string oldName, string newName)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WDeleteFamily(string name)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ #endregion Families functions
+
+ #region Edges functions
+
+ public override CmsError TOOLS_WAddEdge(int toolId, ref EdgeModel edge)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ var tool = ToolTableData.Where(x => x.Id == toolId).FirstOrDefault();
+
+ if (tool == null)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ if (tool.EdgesData.Count >= MAX_EDGES_PER_TOOL)
+ return MAX_EDGES_PER_TOOL_REACHED_ERROR;
+
+ List ids = Enumerable.Range(1, MAX_EDGES_PER_TOOL).ToList();
+
+ foreach (var edgeVal in tool.EdgesData)
+ {
+ ids.Remove(edgeVal.Id);
+ }
+
+ // Get next edge id
+ int nextEdgeId = ids[0];
+
+ try
+ {
+ // Create strings parameters
+ string[] piArgs = new string[5];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = toolId.ToString().PadLeft(5, '0'); //Tool ID
+ piArgs[3] = "00000"; //Cutt. edge ID (00000 > autom)
+ piArgs[4] = "_N_CRCEDN";
+ // Start NC add command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+
+ edge.Id = nextEdgeId;
+
+ cmsError = TOOLS_WUpdateEdge(toolId, ref edge);
+ if (cmsError.IsError())
+ return cmsError;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateEdge(int toolId, ref EdgeModel edge)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ SiemensToolModel tool = ToolTableData.Where(x => x.Id == toolId).FirstOrDefault();
+ if (tool == null)
+ return INCORRECT_PARAMETERS_ERROR;
+ if (tool.ToolType == 9999)
+ return INCORRECT_PARAMETERS_ERROR;
+ try
+ {
+ // Initialize edges configuration
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+ // Get config for current tool type
+ List toolTypeConfig = toolEdgesConfig.EdgesConfig[tool.ToolType];
+ DataSvc dataSvc = new DataSvc();
+ List
- items = new List
- ();
+
+ int edgeLifeOffset = (edge.Id - 1) * 9;
+ if (LIFE_OPTION_ACTIVE) // Check if life option is active
+ {
+ switch (tool.LifeType)
+ {
+ // Add item choosing based on life
+ case SIEMENS_LIFE_TYPE.TIME:
+ {
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 1), Value = edge.PreAlmLife });
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 2), Value = edge.NominalLife });
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 5), Value = edge.ResidualLife });
+ }
+ break;
+
+ case SIEMENS_LIFE_TYPE.COUNT:
+ {
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 3), Value = edge.PreAlmLife });
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 6), Value = edge.NominalLife });
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 4), Value = edge.ResidualLife });
+ }
+ break;
+
+ case SIEMENS_LIFE_TYPE.WEAR:
+ {
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 7), Value = edge.PreAlmLife });
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 9), Value = edge.NominalLife });
+ items.Add(new Item() { Path = string.Format("/Tool/Supervision/data[c{0}, {1}]", tool.Id, edgeLifeOffset + 8), Value = edge.ResidualLife });
+ }
+ break;
+ }
+ }
+ // Edge params
+ int edgeParamsIndex = ((edge.Id - 1) * 35);
+
+ // Set edge id type
+ items.Add(new Item() { Path = string.Format("/Tool/Compensation/edgeData[c{0},{1}]", tool.Id, edgeParamsIndex + 1), Value = tool.ToolType });
+
+ // Update edge type to 9
+ items.Add(new Item() { Path = string.Format("/Tool/Compensation/edgeData[c{0}, {1}]", tool.Id, edgeParamsIndex + 2), Value = 9 });
+
+ // Set edge additional params, read by configuration
+ foreach (EdgeConfigModel conf in toolTypeConfig)
+ {
+ if (edge.EdgeAdditionalParams.ContainsKey(conf.Name))
+ {
+ items.Add(new Item() { Path = string.Format("/Tool/Compensation/edgeData[c{0}, {1}]", tool.Id, edgeParamsIndex + conf.Number), Value = edge.EdgeAdditionalParams[conf.Name] });
+ }
+ }
+
+ dataSvc.Write(items.ToArray());
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WDeleteEdge(int toolId, int edgeId)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Find tool
+ var tool = ToolTableData.Where(x => x.Id == toolId).FirstOrDefault();
+ // If tool not exists, return
+ if (tool == null)
+ return INCORRECT_PARAMETERS_ERROR;
+ // if edge not exists, return
+ if (tool.EdgesData.Where(x => x.Id == edgeId).FirstOrDefault() == null)
+ return INCORRECT_PARAMETERS_ERROR;
+ // If there is only 1 edge, return with error
+ if (tool.EdgesData.Count == 1)
+ return INCORRECT_PARAMETERS_ERROR;
+ try
+ {
+ // Create strings parameters
+ string[] piArgs = new string[5];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = toolId.ToString().PadLeft(5, '0'); //Tool ID (> 00000)
+ piArgs[3] = edgeId.ToString().PadLeft(5, '0'); //Cutt. edge ID (> 00000)
+ piArgs[4] = "_N_DELECE";
+ // Start NC delete command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ return NO_ERROR;
+ }
+
+ #endregion Edges functions
+
+ #region Load/Unload functions
+
+ public override CmsError TOOLS_WLoadToolInMagazine(int magazineId, NewToolInMagazineModel newMagazineTool, ref MountedToolModel newMountedTool)
+ {
+ // Check if magazine is occupied
+ if (MagazineAction.Action != MAGAZINE_ACTIONS.READY)
+ return MAGAZINE_BUSY_ERROR;
+
+ // Get mag config
+ SiemensMagazineConfigModel magConfig = MagazineConfig.Where(x => x.Id == magazineId).FirstOrDefault();
+ if (magConfig == null || !magConfig.LoadingIsActive)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Get magazine position type
+ PositionModel position = MagazinePositionsData.Where(x => x.PositionId == newMagazineTool.PositionId && x.MagazineId == magazineId).FirstOrDefault();
+ if (position == null || position.Disabled)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ if (position.Occupied)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+
+ // Get tool data
+ var tool = GetToolOrMultitool(newMagazineTool.ToolId);
+ if (tool == null)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ // Check if magazine position is occupied
+ MountedToolModel magPos = MagazineMountedTools
+ .Where(x => x.MagazineId == magazineId && x.PositionId == newMagazineTool.PositionId)
+ .FirstOrDefault();
+
+ if (magPos != null)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+
+ // Get position type
+ int newToolPositionType = tool is SiemensToolModel ?
+ (tool as SiemensToolModel).MagazinePositionType :
+ (tool as ShankModel).MagazinePositionType;
+
+ // Check type
+ if (newToolPositionType != position.Type)
+ return TOOL_AND_POSITION_NOT_MATCHING_ERROR;
+
+ // Check if tool can fit in the position considering disabled positions
+ if (magConfig.Type != SIEMENS_MAGAZINE_TYPE.BOX_MAGAZINE)
+ {
+ foreach (var pos in MagazinePositionsData)
+ {
+ if (pos.Disabled && pos.MagazineId == magazineId)
+ {
+ // If magazine is circular, move position before ( for left case ) or after ( right case ) the location you want to mount the tool
+ var right = pos.PositionId < newMagazineTool.PositionId ? pos.PositionId + magConfig.MaxPositions : pos.PositionId;
+ var left = pos.PositionId > newMagazineTool.PositionId ? pos.PositionId - magConfig.MaxPositions : pos.PositionId;
+
+ // Calculate right space needed
+ double rightToBeMount = newMagazineTool.PositionId + ((tool as SiemensToolModel).RightSize / 2.0);
+ if (right < rightToBeMount)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+
+ // Left check
+ // Calculate left space needed
+ double leftToBeMounted = newMagazineTool.PositionId - ((tool as SiemensToolModel).LeftSize / 2.0);
+ if (left > leftToBeMounted)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+ }
+ }
+ }
+ else
+ {
+ // Check if near positions are disabled
+ var posizionDisabled = MagazinePositionsData.Where(
+ x => x.MagazineId == magazineId && x.Disabled == true &&
+ ((x.PositionId > newMagazineTool.PositionId && x.PositionId <= newMagazineTool.PositionId + (tool as SiemensToolModel).RightSize / 2.0)
+ || (x.PositionId < newMagazineTool.PositionId && x.PositionId >= newMagazineTool.PositionId - (tool as SiemensToolModel).LeftSize / 2.0)))
+ .ToList();
+
+ if (posizionDisabled.Count() > 0)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+ }
+
+
+ // Check if tool can fit in the position considering other tools
+ foreach (var mountedTool in MagazineMountedTools)
+ {
+ // Check if is not the same position && if is different check if the position is on the same magazine
+ if (mountedTool.PositionId != newMagazineTool.PositionId && mountedTool.MagazineId == magazineId)
+ {
+ // Get mounted tool data
+ int toolIndex = ToolTableData.FindIndex(x => x.Id == mountedTool.ToolId);
+ if (toolIndex > -1)
+ {
+ int decPosition, incPosition;
+ decPosition = incPosition = mountedTool.PositionId;
+ // If the magazine is a circular magazine move position before ( for left case ) or after ( right case ) the location you want to mount the tool
+ if (magConfig.Type != SIEMENS_MAGAZINE_TYPE.BOX_MAGAZINE)
+ {
+ // If magazine is circular, move position before ( for left case ) or after ( right case ) the location you want to mount the tool
+ decPosition = decPosition < newMagazineTool.PositionId ? decPosition + magConfig.MaxPositions : decPosition;
+ incPosition = incPosition > newMagazineTool.PositionId ? incPosition - magConfig.MaxPositions : incPosition;
+
+ // Right check
+ // Calculate left space occupied
+ double leftMounted = decPosition - (ToolTableData[toolIndex].LeftSize / 2.0);
+ // Calculate right space needed
+ double rightToBeMount = newMagazineTool.PositionId + ((tool as SiemensToolModel).RightSize / 2.0);
+ if (leftMounted < rightToBeMount)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+
+ // Left check
+ // Calculate right space occupied
+ double rightMounted = incPosition + (ToolTableData[toolIndex].RightSize / 2.0);
+ // Calculate left space needed
+ double leftToBeMounted = newMagazineTool.PositionId - ((tool as SiemensToolModel).LeftSize / 2.0);
+ if (rightMounted > leftToBeMounted)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+ }
+ else
+ {
+ // Right check
+ if (newMagazineTool.PositionId < mountedTool.PositionId)
+ {
+ // Calculate left space occupied
+ double leftMounted = mountedTool.PositionId - (ToolTableData[toolIndex].LeftSize / 2.0);
+ // Calculate right space needed
+ double rightToBeMount = newMagazineTool.PositionId + ((tool as SiemensToolModel).RightSize / 2.0);
+ if (leftMounted < rightToBeMount)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+ }
+
+ // Left check
+ // Calculate right space occupied
+ if (newMagazineTool.PositionId > mountedTool.PositionId)
+ {
+ double rightMounted = mountedTool.PositionId + (ToolTableData[toolIndex].RightSize / 2.0);
+ // Calculate left space needed
+ double leftToBeMounted = newMagazineTool.PositionId - ((tool as SiemensToolModel).LeftSize / 2.0);
+ if (rightMounted > leftToBeMounted)
+ return MAGAZINE_POSITION_OCCUPIED_ERROR;
+ }
+ }
+ }
+ }
+ }
+
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ //Load tool in magazine
+ string[] piArgs = new string[8];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = newMagazineTool.ToolId.ToString().PadLeft(5, '0'); //Tool ID (> 00000)
+ piArgs[3] = magConfig.LoadPosition.ToString().PadLeft(5, '0'); ; // Manina carico (valore fisso)
+ piArgs[4] = "09999"; // Magazzino di carico (valore fisso)
+ piArgs[5] = newMagazineTool.PositionId.ToString().PadLeft(5, '0'); // Manina di destinazione (dove caricare l'utensile)
+ piArgs[6] = magazineId.ToString().PadLeft(5, '0'); // Magazzino di destinazione (dove caricare l'utensile)
+ piArgs[7] = "_N_TMMVTL";
+
+ // Start NC load command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ // Mount temporarily till the Siemens notification arrives
+ MoveToolInMagazineList(newMagazineTool.ToolId, magazineId, newMagazineTool.PositionId);
+
+ newMountedTool = new MountedToolModel()
+ {
+ MagazineId = magazineId,
+ PositionId = newMagazineTool.PositionId,
+ ToolId = newMagazineTool.ToolId,
+ ChildTool = tool as SiemensToolModel,
+ ChildShank = null // Todo when multitools work
+ };
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WUnloadToolFromMagazine(int magazineId, int positionId)
+ {
+ if (MagazineAction.Action != MAGAZINE_ACTIONS.READY)
+ return MAGAZINE_BUSY_ERROR;
+
+ // Get mag config
+ SiemensMagazineConfigModel magConfig = MagazineConfig.Where(x => x.Id == magazineId).FirstOrDefault();
+ if (magConfig == null || !magConfig.LoadingIsActive)
+ return INCORRECT_PARAMETERS_ERROR;
+
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ //UnLoad tool in magazine
+ string[] piArgs = new string[8];
+ piArgs[0] = "/NC";
+ piArgs[1] = "401";
+ piArgs[2] = "-0001"; // Tool ID (Fixed, no ID)
+ piArgs[3] = positionId.ToString().PadLeft(5, '0'); // Manina carico (valore fisso)
+ piArgs[4] = magazineId.ToString().PadLeft(5, '0'); // Magazzino di carico (valore fisso)
+ piArgs[5] = magConfig.LoadPosition.ToString().PadLeft(5, '0'); //Manina carico (valore fisso)
+ piArgs[6] = "09999"; // Magazzino da cui scaricare l'utensile
+ piArgs[7] = "_N_TMMVTL";
+
+ // Start NC load command
+ PiSvc pi = new PiSvc(piArgs);
+ pi.Start();
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ //// Smount temporarily till the Siemens notification arrives
+ int magPosIndex = MagazineMountedTools.FindIndex(x => x.MagazineId == magazineId && x.PositionId == positionId);
+ if (magPosIndex >= 0)
+ MagazineMountedTools.Remove(MagazineMountedTools[magPosIndex]);
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WLoadToolIntoShank(int shankId, int positionId, int toolId)
+ {
+ return NO_ERROR;
+
+ // Check if mt exists
+ ShankModel shank = MultitoolsData.Where(x => x.Id == shankId).FirstOrDefault();
+ if (shank == null)
+ return INCORRECT_PARAMETERS_ERROR;
+ // Check if tool can be loaded
+ if (shank.ChildsTools.Count >= MAX_TOOLS_PER_MULTITOOL)
+ return MAX_TOOLS_PER_MULTITOOL_REACHED_ERROR;
+
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ DataSvc dataSvc = new DataSvc();
+
+ int paramId = ((positionId - 1) * 6) + 5;
+ // Write parameter into multitool parameters
+ Item item = new Item()
+ {
+ Path = string.Format("/Tool/MTPlace/mtPlaceData[c{0},{1}]", shankId, paramId),
+ Value = toolId
+ };
+ dataSvc.Write(item);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WUnloadToolFromShank(int shankId, int positionId)
+ {
+ return NO_ERROR;
+
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ DataSvc dataSvc = new DataSvc();
+ int paramId = ((positionId - 1) * 6) + 5;
+ // TC_MTP2
+ Item item = new Item()
+ {
+ Path = string.Format("/Tool/MTPlace/mtPlaceData[c{0},{1}]", shankId, paramId),
+ Value = 0
+ };
+ dataSvc.Write(item);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WStartTDILoading(ushort magazineId, ushort positionId)
+ {
+ List words = new List()
+ {
+ (ushort)(((int)SIEMENS_TDI_ACTION.LOAD << 8) + positionId),
+ magazineId
+ };
+
+ CmsError cmsError = MEM_RWWordList(W, 1, BALLUF_ACTION_DATA.MemType, BALLUF_ACTION_DATA.Address, BALLUF_ACTION_DATA.SubAddress, 2, ref words);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return PLC_WStrobe(BALLUF_ACTION_ACK, BALLUF_ACTION_STROBE, 1);
+ }
+
+ public override CmsError TOOLS_WStartTDIUnloading(ushort magazineId, ushort positionId, ushort toolId)
+ {
+ var mountedTool = MagazineMountedTools.Where(x => x.ToolId == toolId).FirstOrDefault();
+ if (mountedTool == null || (mountedTool.ToolId != toolId && mountedTool.PositionId != positionId))
+ return INCORRECT_PARAMETERS_ERROR;
+
+ List words = new List()
+ {
+ (ushort)(((int)SIEMENS_TDI_ACTION.UNLOAD << 8) + positionId),
+ magazineId,
+ toolId
+ };
+
+ CmsError cmsError = MEM_RWWordList(W, 1, BALLUF_ACTION_DATA.MemType, BALLUF_ACTION_DATA.Address, BALLUF_ACTION_DATA.SubAddress, 2, ref words);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return PLC_WStrobe(BALLUF_ACTION_ACK, BALLUF_ACTION_STROBE, 1);
+ }
+
+ public override CmsError TOOLS_WEmptyBallufTablet(SiemensToolModel tool)
+ {
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Setup status byte
+ BitArray bitArray = new BitArray(new bool[] { tool.IsActive, tool.IsEnabled, tool.IsInhibited, tool.IsMeasured, tool.PreAlarm, tool.InChangeTool, tool.InFixedPlace, tool.IsInUse });
+ int[] statusArray = new int[1];
+ bitArray.CopyTo(statusArray, 0);
+
+ // Setup dimensions byte ( byte is formed by nibble => left_size right_size 0001 0001 )
+ ushort dimensions = (ushort)((((tool.LeftSize << 4) + tool.RightSize) << 8) + 17); // 17 = 0001 0001 ->
+ DataSvc dataSvc = new DataSvc();
+ // Main data
+ byte[] familyName = Encoding.ASCII.GetBytes(tool.FamilyName);
+ List
- items = new List
- {
+ new Item(){ Path = string.Format("DB{0}.DBB0", BALLUF_EMPTY_TABLE.Address), Value = tool.ChildId },
+ new Item(){ Path = string.Format("DB{0}.DBB2[" + familyName.Length +"]", BALLUF_EMPTY_TABLE.Address), Value = familyName },
+ new Item(){ Path = string.Format("DB{0}.DBW34", BALLUF_EMPTY_TABLE.Address), Value = dimensions },
+ new Item(){ Path = string.Format("DB{0}.DBW36", BALLUF_EMPTY_TABLE.Address), Value = tool.MagazinePositionType },
+ new Item(){ Path = string.Format("DB{0}.DBW38", BALLUF_EMPTY_TABLE.Address), Value = statusArray[0] },
+ new Item(){ Path = string.Format("DB{0}.DBW40", BALLUF_EMPTY_TABLE.Address), Value = (int)tool.LifeType },
+ new Item(){ Path = string.Format("DB{0}.DBD42", BALLUF_EMPTY_TABLE.Address), Value = tool.MaxSpeed },
+ new Item(){ Path = string.Format("DB{0}.DBD46", BALLUF_EMPTY_TABLE.Address), Value = tool.Load },
+ new Item(){ Path = string.Format("DB{0}.DBD50", BALLUF_EMPTY_TABLE.Address), Value = tool.Gamma },
+ new Item(){ Path = string.Format("DB{0}.DBD54", BALLUF_EMPTY_TABLE.Address), Value = tool.MaxLoadPctAutoload },
+ new Item(){ Path = string.Format("DB{0}.DBD58", BALLUF_EMPTY_TABLE.Address), Value = tool.MinLoadPctAutoload },
+ new Item(){ Path = string.Format("DB{0}.DBD62", BALLUF_EMPTY_TABLE.Address), Value = tool.ToolTypeCode },
+ //new Item(){ Path = string.Format("DB{0}.DBB64:STRING", BALLUF_EMPTY_TABLE.Address), Value = tool.FamilyName },
+
+ new Item(){ Path = string.Format("DB{0}.DBW70", BALLUF_EMPTY_TABLE.Address), Value = 1 },
+
+ // Edge data
+ new Item(){ Path = string.Format("DB{0}.DBW86", BALLUF_EMPTY_TABLE.Address), Value = tool.ToolType },
+ new Item(){ Path = string.Format("DB{0}.DBW88", BALLUF_EMPTY_TABLE.Address), Value = 9 },
+ };
+
+ EdgeModel edge = tool.EdgesData[0];
+
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+ // Get config for current tool type
+ List toolTypeConfig = toolEdgesConfig.EdgesConfig[tool.ToolType];
+ // Set edge additional params, read by configuration
+ foreach (EdgeConfigModel conf in toolTypeConfig)
+ {
+ if (edge.EdgeAdditionalParams.ContainsKey(conf.Name) && toolEdgesConfig.TDIEdgeFields.ContainsKey(conf.Path))
+ {
+ items.Add(new Item()
+ {
+ Path = string.Format(toolEdgesConfig.TDIEdgeFields[conf.Path], BALLUF_EMPTY_TABLE.Address),
+ Value = edge.EdgeAdditionalParams[conf.Name]
+ });
+ }
+ }
+
+ // Life Parameters
+ switch (tool.LifeType)
+ {
+ case SIEMENS_LIFE_TYPE.TIME:
+ {
+ items.AddRange(new List
- ()
+ {
+ new Item() { Path = string.Format("DB{0}.DBD186", BALLUF_EMPTY_TABLE.Address), Value = edge.ResidualLife }, // MOP2
+ new Item() { Path = string.Format("DB{0}.DBD194", BALLUF_EMPTY_TABLE.Address), Value = edge.NominalLife }, // MOP11
+ new Item() { Path = string.Format("DB{0}.DBD182", BALLUF_EMPTY_TABLE.Address), Value = edge.PreAlmLife } // MOP1
+ });
+ }
+ break;
+
+ case SIEMENS_LIFE_TYPE.COUNT:
+ {
+ items.Add(new Item() { Path = string.Format("DB{0}.DBW192", BALLUF_EMPTY_TABLE.Address), Value = edge.ResidualLife }); // MOP4
+ items.Add(new Item() { Path = string.Format("DB{0}.DBW198", BALLUF_EMPTY_TABLE.Address), Value = edge.NominalLife }); // MOP13
+ items.Add(new Item() { Path = string.Format("DB{0}.DBW190", BALLUF_EMPTY_TABLE.Address), Value = edge.PreAlmLife }); // MOP3
+ }
+ break;
+
+ case SIEMENS_LIFE_TYPE.WEAR:
+ {
+ items.Add(new Item() { Path = string.Format("DB{0}.DBD204", BALLUF_EMPTY_TABLE.Address), Value = edge.ResidualLife }); // MOP6
+ items.Add(new Item() { Path = string.Format("DB{0}.DBD208", BALLUF_EMPTY_TABLE.Address), Value = edge.NominalLife }); // MOP15
+ items.Add(new Item() { Path = string.Format("DB{0}.DBD200", BALLUF_EMPTY_TABLE.Address), Value = edge.PreAlmLife }); // MOP5
+ }
+ break;
+ }
+
+ try
+ {
+ dataSvc.Write(items.ToArray());
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return WBallufAction(SIEMENS_TDI_ACTION.ABORT);
+ }
+
+ public override CmsError TOOLS_WAbortBallufTablet()
+ {
+ return WBallufAction(SIEMENS_TDI_ACTION.ABORT);
+ }
+
+ private CmsError WBallufAction(SIEMENS_TDI_ACTION action)
+ {
+ byte act = (byte)action;
+ CmsError cmsError = MEM_RWByte(W, 1, BALLUF_ACTION_DATA.MemType, BALLUF_ACTION_DATA.Address, BALLUF_ACTION_DATA.SubAddress, 0, ref act);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return PLC_WStrobe(BALLUF_ACTION_ACK, BALLUF_ACTION_STROBE, 1);
+ }
+
+ #endregion Load/Unload functions
+
+ public override CmsError TOOLS_RMagazinePositions(ref List positions)
+ {
+ positions = MagazinePositionsData;
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdatePosition(PositionModel position)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ try
+ {
+ DataSvc dataSvc = new DataSvc();
+ int paramId = ((position.PositionId - 1) * 11) + 5;
+ // TC_MTP2
+ Item item = new Item()
+ {
+ Path = string.Format("/Tool/Magazine/placeData[c{0} , {1}]", position.MagazineId, paramId)
+ };
+ dataSvc.Read(item);
+
+ item.Value = SetBitValue(Convert.ToInt32(item.Value), position.Disabled, 1);
+ dataSvc.Write(item);
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_RMountedTools(int magazineId, ref List magazinePos)
+ {
+ if (magazineId <= 0)
+ return INCORRECT_PARAMETERS_ERROR;
+ // Filter by magazine id
+ magazinePos = MagazineMountedTools
+ .Where(x => x.MagazineId == magazineId)
+ .ToList();
+
+ foreach (var pos in magazinePos)
+ {
+ var tool = GetToolOrMultitool(pos.ToolId);
+ if (tool is SiemensToolModel)
+ pos.ChildTool = tool as SiemensToolModel;
+ else if (tool is ShankModel)
+ pos.ChildShank = tool as ShankModel;
+ }
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_RAvailableTools(ref List multiTools, ref List tools)
+ {
+ List occupiedIds = new List();
+ // Find ids of tools mounted in the magazines
+ foreach (var mounted in MagazineMountedTools)
+ {
+ var tmp = mounted as MountedToolModel;
+
+ var tool = GetToolOrMultitool(tmp.ToolId);
+
+ //if (tool is ShankModel) // If multitool
+ //{
+ // occupiedIds.Add((tool as ShankModel).Id); // Add multitool id
+ //} else
+ if (tool is SiemensToolModel) // If tool
+ {
+ occupiedIds.Add((tool as SiemensToolModel).Id);
+ }
+ }
+
+ //// Add tools mounted in multitools
+ //foreach (var multi in MultitoolsData)
+ //{
+ // if (multi.ChildsTools.Count > 0)
+ // mountedIds.AddRange(multi.ChildsTools.Select(x => x.Id).ToList());
+ //}
+
+ // Filter tools
+ tools = ToolTableData
+ .Where(x => !occupiedIds.Contains(x.Id))
+ .ToList();
+
+ //// Filter multitools
+ //multiTools = MultitoolsData
+ // .Where(x => !mountedIds.Contains(x.Id))
+ // .ToList();
+
+ return NO_ERROR;
+ }
+
+ private object GetToolOrMultitool(int toolId)
+ {
+ int toolIndex = ToolTableData.FindIndex(x => x.Id == toolId);
+ if (toolIndex >= 0)
+ {
+ return ToolTableData[toolIndex];
+ }
+ //else
+ //{
+ // int multiIndex = MultitoolsData.FindIndex(x => x.Id == toolId);
+ // if (multiIndex >= 0)
+ // return MultitoolsData[multiIndex];
+ //}
+
+ return null;
+ }
+
+ public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction)
+ {
+ magazineAction = MagazineAction;
+ return NO_ERROR;
+ }
+
+ #endregion Siemens Tool Management
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Nc Tool Manager
+
+ public override CmsError TOOLS_RMagazineConfig(ref List config)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WOptions(ToolManagerOptionsModel options)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_ROffset(short offsetId, ref OffsetModel offset)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WOffset(short offsetId, ref OffsetModel offset)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WStartEditData()
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WStopEditData()
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateTools(List list)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateFamilies(List list)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateShanks(List list)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WUpdateMagazinePositions(List list)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WStartEditTooling(int magazineId)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WStopEditTooling(int magazineId)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WRestoreBackup()
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_RUpdatedToolsData(ref Dictionary updatedStatus, ref Dictionary updatedLives)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_RStoredData(ref List tools, ref List families, ref List shanks)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_RMagazineBlock(ref List ids)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_WFreeMagazines()
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_RMagazineStatus(ref Dictionary magazineStatus)
+ {
+ return FUNCTION_NOT_ALLOWED_ERROR;
+ }
+
+ public override CmsError TOOLS_RAdatpivePathStep(ref Byte step)
+ {
+ // Check ACK
+ CmsError cmsError = MEM_RWByte(R, 0, SELF_ADAPTIVE_PATH.MemType, SELF_ADAPTIVE_PATH.Address, SELF_ADAPTIVE_PATH.SubAddress, 0, ref step);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ public override CmsError TOOLS_WAdatpivePathStep(Byte step)
+ {
+ // Check ACK
+ CmsError cmsError = MEM_RWByte(W, 0, SELF_ADAPTIVE_PATH.MemType, SELF_ADAPTIVE_PATH.Address, SELF_ADAPTIVE_PATH.SubAddress, 0, ref step);
+ if (cmsError.IsError())
+ return cmsError;
+
+ return NO_ERROR;
+ }
+
+ #endregion Nc Tool Manager
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Subordinate Private Functions
+
+ private DataSvc HighPriorityDataSvc()
+ {
+ return new DataSvc()
+ {
+ PriorityFlag = SlPriority.highPriority,
+ Timeout = TimeoutConn
+ };
+ }
+
+ private DataSvc DefaultPriorityDataSvc()
+ {
+ return new DataSvc()
+ {
+ PriorityFlag = SlPriority.defaultPriority,
+ Timeout = TimeoutConn
+ };
+ }
+
+ private DataSvc LowPriorityDataSvc()
+ {
+ return new DataSvc()
+ {
+ PriorityFlag = SlPriority.lowPriority,
+ Timeout = TimeoutConn
+ };
+ }
+
+ // Manage the Alarms - Called automatically on changes
+ private void AlarmsChanged(Guid guid, Alarm[] alarms)
+ {
+ try
+ {
+ if (alarms != null)
+ SiemensAlarms = alarms.ToArray();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+
+ private void NcLanguageChanged(string language)
+ {
+ SiemensAlmSvc.UnSubscribe(AlarmsChanged);
+ // SiemensAlmSvc.Dispose();
+ SiemensAlmSvc = new AlarmSvc(language);
+ SiemensAlmSvc.Subscribe(AlarmsChanged);
+ }
+
+ private int SetBitValue(int intVal, bool val, int bitIndex)
+ {
+ if (val)
+ return intVal | (1 << (bitIndex - 1));
+ else
+ return intVal & ~(1 << (bitIndex - 1));
+ }
+
+ //Manage the Mode
+ private PROC_MODE ConvertToSTEPMode(uint mode, uint JogMode, uint AdvMode)
+ {
+ if (mode == 0)
+ {
+ if (AdvMode == 0)
+ return (JogMode < 6) ? PROC_MODE.JOGINC : PROC_MODE.JOG;
+ else if (AdvMode == 1)
+ return PROC_MODE.RETPROF;
+ else if (AdvMode == 2)
+ return PROC_MODE.TEACH;
+ else if (AdvMode == 3)
+ return PROC_MODE.REF;
+ }
+ else if (mode == 1)
+ return PROC_MODE.MDI;
+ else if (mode == 2)
+ return PROC_MODE.AUTO;
+
+ return PROC_MODE.ERROR;
+ }
+
+ //Manage the Status
+ private PROC_STATUS ConvertToSTEPStatus(uint status)
+ {
+ switch (status)
+ {
+ case 0: return PROC_STATUS.IDLE;
+ case 1: return PROC_STATUS.RUN;
+ case 2: return PROC_STATUS.HOLD;
+ }
+ return PROC_STATUS.ERROR;
+ }
+
+ //Check Bit In Range
+ private CmsError CheckBitRange(int bitnum)
+ {
+ if (bitnum < 0 || bitnum > 7)
+ return BIT_NOT_IN_RANGE_ERROR;
+
+ return NO_ERROR;
+ }
+
+ // Check if Memory Area is corrected
+ private CmsError ConvertMemToPath(MEMORY_TYPE MemoryType, int Address, int SubAddress, int SubBit, int Qty, char MemAccess, out string item)
+ {
+ char[] allowedAccess = { 'X', 'B', 'W', 'D' };
+
+ //Check if is the right area and allowed type
+ if (!MemoryType.ToString().StartsWith(SIEMENS_MEMTYPE) || !allowedAccess.Contains(MemAccess) || Qty < 1)
+ {
+ item = "";
+ return INCORRECT_PARAMETERS_ERROR;
+ }
+ else
+ {
+ //If is Bit Access change access type
+ if (MemAccess == 'X')
+ item = "DB" + Address + ".DB" + MemAccess + SubAddress + "." + SubBit;
+ else
+ item = "DB" + Address + ".DB" + MemAccess + SubAddress + "[" + Qty + "]";
+
+ return NO_ERROR;
+ }
+ }
+
+ // Check if NC is connected
+ private CmsError CheckConnection()
+ {
+ if (!NC_IsConnected())
+ return NOT_CONNECTED_ERROR;
+
+ return NO_ERROR;
+ }
+
+ ///
+ /// Check if PLC is responding to Ping
+ ///
+ ///
+ private CmsError CheckS7Ping()
+ {
+
+ // faccio ping...
+ if(testPing() != IPStatus.Success)
+ return PLC_IP_NOT_FOUND_ERROR;
+ return NO_ERROR;
+ }
+
+
+ ///
+ /// Ping test to configured Ip address
+ ///
+ ///
+ private IPStatus testPing()
+ {
+ IPStatus answ = IPStatus.Unknown; ;
+ IPAddress address;
+ PingReply reply;
+ Ping pingSender = new Ping();
+ address = IPAddress.Loopback;
+ IPAddress.TryParse(this.Ip, out address);
+ reply = pingSender.Send(address, 100);
+ answ = reply.Status;
+ return answ;
+ }
+
+ //Manage the Exception Launch
+ private CmsError ManageException(Exception ex)
+ {
+ //Catch the Siemens exceptions
+ if (ex is OperateMissingOptionException && ex.Message.Contains(OptionHMINotRunning) || ex.Message.Contains("CORBA"))
+ {
+ Connected = false;
+ return SIEMENS_HMI_NOT_RUNNING_ERROR;
+ }
+ else if (ex is FileNotFoundException && ex.Message.Contains(HMIDllName))
+ {
+ return SIEMENS_ENVIRONMENT_NOT_FOUND_ERROR;
+ }
+ else if (ex.Message.Contains(NcNotFound) || ex.Message.Contains(NcNotFound2) || ex.Message.Contains(NcNotFound3) || ex.Message.Contains("Read() failed:"))
+ {
+ Connected = false;
+ return NOT_CONNECTED_ERROR;
+ }
+ else if (ex.Message.Contains("m_pSlToolMngmntSvc"))
+ {
+ return SIEMENS_TOOL_TABLE_ERROR;
+ }
+ else
+ {
+ return CmsError.InternalError(ex.Message, ex);
+ }
+ }
+
+ // Create and return CmsError object
+ private CmsError GetError(string message)
+ {
+ return CmsError.NcError(message);
+ }
+
+ //Read Static Data
+ private CmsError ReadStaticNCData()
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ //Read oly one time every X seconds
+ if (DateTime.Now - Last_Static_Read > new TimeSpan(NC_MIN_SEC_READ_STATIC_DATA * TimeSpan.TicksPerSecond))
+ {
+ //Try to get information
+ try
+ {
+ DataSvc ReadStaticData = DefaultPriorityDataSvc();
+ Item ItemNcType = new Item(NC_TYPE_PATH);
+ Item ItemNcVersion = new Item(NC_VERSION_PATH);
+ Item ItemMaxChannelNo = new Item(MAX_CHANNEL_NO_PATH);
+ Item ItemConfChannelNo = new Item(CONF_CHANNEL_NO_PATH);
+ Item ItemLanguage = new Item(LANGUAGE_PATH);
+ Item ItemSerialNumber = new Item(SERIAL_NO_PATH);
+ Item ItemUnitOfMeasure = new Item(UNIT_OF_MEASURE);
+ cmsError = ConvertMemToPath(MATR_MACCH_SIEMENS.MemType, MATR_MACCH_SIEMENS.Address, MATR_MACCH_SIEMENS.SubAddress, 0, 1, 'W', out string itemString);
+
+ if (cmsError.IsError())
+ return cmsError;
+ Item ItemMachineNumber = new Item(itemString);
+
+ //Read All Data
+ ReadStaticData.Read(ItemNcType);
+ ReadStaticData.Read(ItemNcVersion);
+ ReadStaticData.Read(ItemMaxChannelNo);
+ ReadStaticData.Read(ItemConfChannelNo);
+ ReadStaticData.Read(ItemLanguage);
+ ReadStaticData.Read(ItemSerialNumber);
+ ReadStaticData.Read(ItemMachineNumber);
+ ReadStaticData.Read(ItemUnitOfMeasure);
+
+ //Setup variables
+ Cnc_name = GetName((uint)ItemNcType.Value);
+ Cnc_SftVersion = Regex.Replace(((double)ItemNcVersion.Value).ToString(), ".{2}", "$0.").TrimEnd('.'); ;
+ Cnc_SeriesNum = ((string)ItemSerialNumber.Value);
+
+ MaxChannelNo = (uint)ItemMaxChannelNo.Value;
+ ConfChannelNo = (uint)ItemConfChannelNo.Value;
+ SiemensLanguage = (uint)ItemLanguage.Value;
+ Cms_MachNumber = ((uint)ItemMachineNumber.Value).ToString();
+ UnitOfMeasure = (uint)ItemUnitOfMeasure.Value == 0 ? MILLIMETERS : INCHES;
+
+ //Save NOW
+ Last_Static_Read = DateTime.Now;
+ }
+ catch (Exception ex)
+ {
+ return ManageException(ex);
+ }
+ }
+
+ return NO_ERROR;
+ }
+
+ // Convert the internal Name var in Readable STEP Name
+ private string GetName(uint value)
+ {
+ string name = "Siemens ";
+ switch (value)
+ {
+ case 0: name += "840D pl"; break;
+ case 1000: name += "FM-NC"; break;
+ case 2000: name += "810D pl"; break;
+ case 3000: name += "802S"; break;
+ case 4000: name += "802D pl"; break;
+ case 5000: name += "840Di pl"; break;
+ case 6000: name += "SOLUTIONLINE"; break;
+ case 10700: name += "840D sl"; break;
+ case 14000: name += "802D sl T/M - N/G - C/U"; break;
+ case 15000: name += "840Di sl"; break;
+ }
+ return name;
+ }
+
+ //Convert to Step Language
+ private CultureInfo ConvertToSTEPLanguage(uint language)
+ {
+ switch (language)
+ {
+ case 1: return new CultureInfo("de");
+ case 2: return new CultureInfo("fr");
+ case 3: return new CultureInfo("en");
+ case 4: return new CultureInfo("es");
+ case 6: return new CultureInfo("it");
+ case 7: return new CultureInfo("nl");
+ case 8: return new CultureInfo("zh-CHS");
+ case 9: return new CultureInfo("sv");
+ case 18: return new CultureInfo("hu");
+ case 19: return new CultureInfo("fi");
+ case 26: return new CultureInfo("el");
+ case 28: return new CultureInfo("cs");
+ case 50: return new CultureInfo("pt-BR");
+ case 53: return new CultureInfo("pl");
+ case 55: return new CultureInfo("da");
+ case 57: return new CultureInfo("ru");
+ case 65: return new CultureInfo("hr-HR");
+ case 68: return new CultureInfo("sk");
+ case 69: return new CultureInfo("sl");
+ case 72: return new CultureInfo("ro");
+ case 75: return new CultureInfo("bg");
+ case 80: return new CultureInfo("zh-CHT");
+ case 85: return new CultureInfo("ko");
+ case 87: return new CultureInfo("ja");
+ case 89: return new CultureInfo("tr");
+ case 122: return new CultureInfo("id");
+ case 212: return new CultureInfo("th");
+ case 213: return new CultureInfo("vi");
+ case 230: return new CultureInfo("ms");
+ default: return new CultureInfo("en");
+ }
+ }
+
+ //Convert to Step Language
+ private string ConvertToNCLanguage(CultureInfo language)
+ {
+ return language.ThreeLetterISOLanguageName;
+ }
+
+ private int SwapIntEndianFormat(int value)
+ {
+ var b1 = (value >> 0) & 0xff;
+ var b2 = (value >> 8) & 0xff;
+ var b3 = (value >> 16) & 0xff;
+ var b4 = (value >> 24) & 0xff;
+
+ return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
+ }
+
+ private short SwapShortEndianFormat(short value)
+ {
+ var b1 = (value >> 0) & 0xff;
+ var b2 = (value >> 8) & 0xff;
+
+ return (short)(b1 << 8 | b2 << 0);
+ }
+
+ private ushort SwapShortEndianFormat(ushort value)
+ {
+ var b1 = (value >> 0) & 0xff;
+ var b2 = (value >> 8) & 0xff;
+
+ return (ushort)(b1 << 8 | b2 << 0);
+ }
+
+ private List ChangeIntListEndianess(List bigEndianvalues)
+ {
+ List littleEndianValues = new List();
+ foreach (int value in bigEndianvalues)
+ {
+ var a = SwapIntEndianFormat(value);
+ littleEndianValues.Add(a);
+ }
+
+ return littleEndianValues;
+ }
+
+ private List ChangeUShortListEndianess(List bigEndianvalues)
+ {
+ List littleEndianValues = new List();
+ foreach (ushort value in bigEndianvalues)
+ {
+ var a = SwapShortEndianFormat(value);
+ littleEndianValues.Add(a);
+ }
+
+ return littleEndianValues;
+ }
+
+ private bool PositionContainsTool(MountedToolModel mounted, int toolId)
+ {
+ if (mounted.ToolId == toolId)
+ return true;
+ //else
+ //{
+ // // Check if tool is a multitool child
+ // foreach (var multi in MultitoolsData)
+ // {
+ // // Check childs id
+ // int index = multi.ChildsTools.FindIndex(x => x.Id == toolId);
+ // if (index >= 0)
+ // return true;
+ // }
+ //}
+
+ return false;
+ }
+
+ //private void CheckData(object obj, List config)
+ //{
+ // foreach(PropertyInfo prop in obj.GetType().GetProperties())
+ // {
+ // bool val = config.Where(x => x.Name == prop.Name).Select(x => x.);
+ // }
+ //}
+
+ private string ConvertStepToSiemensScreen(SCREEN_PAGE page)
+ {
+ switch (page)
+ {
+ case SCREEN_PAGE.Siemens_Machine: return "AreaMachine";
+ case SCREEN_PAGE.Siemens_Parameter: return "AreaParameter";
+ case SCREEN_PAGE.Siemens_Program: return "AreaProgramEdit";
+ case SCREEN_PAGE.Siemens_ProgramManager: return "AreaProgramManager";
+ case SCREEN_PAGE.Siemens_Setup: return "AreaStartup";
+ case SCREEN_PAGE.Siemens_Diagnostics: return "AreaDiagnosis";
+ default: return "";
+ }
+ }
+
+ #endregion Subordinate Private Functions
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #region Siemens Tool private functions
+
+ private string[] ReadToolTableFile()
+ {
+ // Create a configuration file
+ FileStream f = new FileStream(LOCALE_TOOL_FILE_PATH, FileMode.Create);
+
+ // Read siemens configuration file
+ CmsError cmsError = FILES_RProgramToFile(NC_TOOL_FILE_PATH, f);
+ f.Close();
+
+ return File.ReadAllLines(LOCALE_TOOL_FILE_PATH);
+ }
+
+ private void MagazinePositionEnabled_OnChange(Guid guid, Item[] items, DataSvcStatus[] status)
+ {
+ int i = 0;
+ // Parse each new item
+ foreach (Item item in items)
+ {
+ if (status[i].Ok)
+ {
+ // Get Ids
+ string[] ids = item.SymbolicName.Split('_');
+ int magazineId = Convert.ToInt32(ids[0]);
+ int positionId = Convert.ToInt32(ids[1]);
+
+ foreach (PositionModel pos in MagazinePositionsData)
+ {
+ // Find position
+ if (pos.PositionId == positionId && pos.MagazineId == magazineId)
+ {
+ // Set Value
+ pos.Disabled = GetBitValue(Convert.ToInt32(item.Value), 0);
+ }
+ }
+ }
+
+ i++;
+ }
+ }
+
+ private void MagazineAction_OnChange(Guid guid, Item item, DataSvcStatus status)
+ {
+ CmsError cmsError = NO_ERROR;
+ if (Connected == false)
+ NC_Connect();
+
+ List wordList = new List();
+ cmsError = MEM_RWWordList(R, 0, MAGAZINE_ACTION.MemType, MAGAZINE_ACTION.Address, MAGAZINE_ACTION.SubAddress + 2, 6, ref wordList);
+ if (cmsError.IsError())
+ {
+ MagazineAction = new MagazineActionModel()
+ {
+ Action = MAGAZINE_ACTIONS.NOT_READY,
+ Tool = null,
+ SecondTool = null,
+ OriginMagazine = 0,
+ OriginPosition = 0,
+ DestinationMagazine = 0,
+ DestinationPosition = 0
+ };
+ }
+ else
+ {
+ MagazineActionToolModel tool = null;
+ MagazineActionToolModel secondTool = null;
+
+ // Get the first tool if exists
+ ushort toolId = wordList[0];
+ if (toolId != 0)
+ tool = ToolTableData
+ .Where(x => x.Id == toolId)
+ .Select(x => new MagazineActionToolModel()
+ {
+ Id = x.Id,
+ IsMultitool = false,
+ Name = x.FamilyName,
+ ToolType = x.ToolType
+ }).FirstOrDefault();
+
+ // Get the second tool if exists
+ toolId = wordList[1];
+ if (toolId != 0)
+ secondTool = ToolTableData
+ .Where(x => x.Id == toolId)
+ .Select(x => new MagazineActionToolModel()
+ {
+ Id = x.Id,
+ IsMultitool = false,
+ Name = x.FamilyName,
+ ToolType = x.ToolType
+ }).FirstOrDefault();
+
+ // Populate model with new data
+ MagazineAction = new MagazineActionModel()
+ {
+ Action = (MAGAZINE_ACTIONS)Convert.ToInt32(item.Value),
+ Tool = tool,
+ SecondTool = secondTool,
+ OriginMagazine = wordList[4],
+ OriginPosition = wordList[5],
+ DestinationMagazine = wordList[2],
+ DestinationPosition = wordList[3]
+ };
+ }
+ }
+
+ private void PopulateToolsTableFromFileStrings(string[] toolsStrings)
+ {
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+
+ int lastFirstId = 0;
+ int lastSecondId = 0;
+ int toolIndex = 0;
+ int edgeIndex = 0;
+ // int multitoolIndex = 0;
+
+ // Foreach string
+ for (int i = 0; i < toolsStrings.Count(); i++)
+ {
+ string actualString = toolsStrings[i]; // Get actual string data
+
+ GetIdsFromSiemensToolString(actualString, out int firstId, out int secondId); // find ids from current string
+
+ if (firstId != 0)
+ {
+ // If tool is changed, change current index tool
+ if (lastFirstId != firstId)
+ {
+ toolIndex = ToolTableData.FindIndex(x => x.Id == firstId);
+ // multitoolIndex = MultitoolsData.FindIndex(x => x.Id == firstId);
+ }
+
+ // Check if the key string has only 1 id
+ if (secondId == 0)
+ {
+ switch (GetStringUntilOrEmpty(actualString)) // Cut string until [ character
+ {
+ case "$TC_TP1":
+ {
+ ToolTableData.Add(new SiemensToolModel()
+ {
+ Id = firstId,
+ ChildId = Convert.ToInt32(actualString.Split('=').LastOrDefault())
+ });
+ // Update Index
+ toolIndex = ToolTableData.Count - 1;
+ }
+ break;
+
+ case "$TC_TP2":
+ {
+ string familyName = actualString.Split('=').LastOrDefault().Replace("\"", "");
+ ToolTableData[toolIndex].FamilyName = familyName;
+ // Add new family with new tool
+ AddOrUpdateFamilyChild(familyName);
+ }
+ break;
+
+ case "$TC_TP3":
+ ToolTableData[toolIndex].LeftSize = Convert.ToByte(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP4":
+ ToolTableData[toolIndex].RightSize = Convert.ToByte(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP7":
+ ToolTableData[toolIndex].MagazinePositionType = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP8":
+ {
+ // Get tool status and read each bit
+ int toolStatus = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+
+ ToolTableData[toolIndex].IsActive = GetBitValue(toolStatus, 0);
+ ToolTableData[toolIndex].IsEnabled = GetBitValue(toolStatus, 1);
+ ToolTableData[toolIndex].IsInhibited = GetBitValue(toolStatus, 2);
+ ToolTableData[toolIndex].IsMeasured = GetBitValue(toolStatus, 3);
+ ToolTableData[toolIndex].PreAlarm = GetBitValue(toolStatus, 4);
+ ToolTableData[toolIndex].InChangeTool = GetBitValue(toolStatus, 5);
+ ToolTableData[toolIndex].InFixedPlace = GetBitValue(toolStatus, 6);
+ ToolTableData[toolIndex].IsInUse = GetBitValue(toolStatus, 7);
+ }
+ break;
+
+ case "$TC_TP9":
+ ToolTableData[toolIndex].LifeType = (SIEMENS_LIFE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP_MAX_VELO":
+ ToolTableData[toolIndex].MaxSpeed = Convert.ToDouble(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ //case "$TC_TP_MAX_ACC":
+ // ToolTableData[toolIndex].MaxAcceleration = Convert.ToDouble(actualString.Split('=').LastOrDefault(), numberFormat);
+ // break;
+ // Custom CMS fields
+ case "$TC_TPC1":
+ ToolTableData[toolIndex].Load = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC2":
+ ToolTableData[toolIndex].Gamma = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC3":
+ ToolTableData[toolIndex].MaxLoadPctAutoload = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC4":
+ ToolTableData[toolIndex].MinLoadPctAutoload = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC5":
+ ToolTableData[toolIndex].ToolTypeCode = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ //*SHANK FIX*case "$TC_MTPN":
+ // {
+ // // Insert new multitool
+ // MultitoolsData.Add(new ShankModel()
+ // {
+ // Id = firstId,
+ // MaxChilds = Convert.ToInt32(actualString.Split('=').LastOrDefault())
+ // });
+ // // Update Index
+ // multitoolIndex = MultitoolsData.Count - 1;
+ // }
+ // break;
+
+ //case "$TC_MTP2":
+ // MultitoolsData[multitoolIndex].Name = actualString.Split('=').LastOrDefault().Replace("\"", "");
+ // break;
+
+ //case "$TC_MTP3":
+ // MultitoolsData[multitoolIndex].LeftSize = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ // break;
+
+ //case "$TC_MTP4":
+ // MultitoolsData[multitoolIndex].RightSize = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ // break;
+
+ //case "$TC_MTP7":
+ // MultitoolsData[multitoolIndex].MagazinePositionType = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ // break;
+
+ //case "$TC_MTP8":
+ // {
+ // // Get tool status
+ // byte toolStatus = Convert.ToByte(actualString.Split('=').LastOrDefault());
+
+ // MultitoolsData[multitoolIndex].IsEnabled = GetBitValue(toolStatus, 1);
+ // MultitoolsData[multitoolIndex].IsInhibited = GetBitValue(toolStatus, 2);
+ // MultitoolsData[multitoolIndex].InChangeTool = GetBitValue(toolStatus, 3);
+ // MultitoolsData[multitoolIndex].InFixedPlace = GetBitValue(toolStatus, 4);
+ // MultitoolsData[multitoolIndex].InUse = GetBitValue(toolStatus, 7);
+ // }
+ // break;
+
+ case "$TC_MAP1":
+ {
+ // Magazine type
+ SiemensMagazineConfigModel mag = MagazineConfig.Where(x => x.Id == firstId).FirstOrDefault();
+ if (mag == null)
+ {
+ bool active = true;
+ SIEMENS_MAGAZINE_TYPE type = (SIEMENS_MAGAZINE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ if (type == SIEMENS_MAGAZINE_TYPE.MAGAZINE_LOADING_STATION || type == SIEMENS_MAGAZINE_TYPE.MAGAZINE_TOOL_BUFFER)
+ active = false;
+
+ MagazineConfig.Add(new SiemensMagazineConfigModel()
+ {
+ Id = (short)firstId,
+ Type = (SIEMENS_MAGAZINE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault()),
+ LoadingIsActive = active
+ });
+ }
+ else
+ mag.Type = (SIEMENS_MAGAZINE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ }
+ break;
+
+ case "$TC_MAP2":
+ {
+ // Magazine Name
+ SiemensMagazineConfigModel mag = MagazineConfig.Where(x => x.Id == firstId).FirstOrDefault();
+ if (mag != null)
+ mag.Name = actualString.Split('=').LastOrDefault().Replace("\"", "");
+ }
+ break;
+
+ case "$TC_MAP7":
+ {
+ // Add max number of magazine positions
+ SiemensMagazineConfigModel mag = MagazineConfig.Where(x => x.Id == firstId).FirstOrDefault();
+ if (mag != null)
+ mag.MaxPositions = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ }
+ break;
+ }
+ }
+ else // If the key string has 2 ids ex: $TC_DP1[1,3]
+ {
+ // If secondId is changed, change current edge id
+ if (lastSecondId != secondId && toolIndex >= 0)
+ edgeIndex = ToolTableData[toolIndex].EdgesData.FindIndex(x => x.Id == secondId);
+
+ switch (GetStringUntilOrEmpty(actualString))
+ {
+ case "$TC_DP1":
+ {
+ if (secondId == 1) // Read tool type from first edge type
+ ToolTableData[toolIndex].ToolType = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ // Add new edge
+ ToolTableData[toolIndex].EdgesData.Add(new EdgeModel() { Id = secondId });
+ edgeIndex = ToolTableData[toolIndex].EdgesData.Count - 1; // Update Index
+ }
+ break;
+
+ case "$TC_MOP1":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.TIME)
+ {
+ tool
+ .EdgesData[edgeIndex]
+ .PreAlmLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP2":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.TIME)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .ResidualLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP11":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.TIME)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .NominalLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP3":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.COUNT)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .PreAlmLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP4":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.COUNT)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .ResidualLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP13":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.COUNT)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .NominalLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP6":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.WEAR)
+ {
+ tool
+ .EdgesData[edgeIndex]
+ .ResidualLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP15":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.WEAR)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .NominalLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP5":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ if (tool.LifeType == SIEMENS_LIFE_TYPE.WEAR)
+ {
+ ToolTableData[toolIndex]
+ .EdgesData[edgeIndex]
+ .PreAlmLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ //case "$TC_DP2":
+ case "$TC_DP3":
+ case "$TC_DP4":
+ case "$TC_DP5":
+ case "$TC_DP6":
+ case "$TC_DP7":
+ case "$TC_DP8":
+ case "$TC_DP9":
+ case "$TC_DP10":
+ case "$TC_DP11":
+ case "$TC_DP12":
+ case "$TC_DP13":
+ case "$TC_DP14":
+ case "$TC_DP15":
+ case "$TC_DP16":
+ case "$TC_DP17":
+ case "$TC_DP21":
+ case "$TC_DP22":
+ case "$TC_DP23":
+ case "$TC_DP24":
+ case "$TC_DPV":
+ case "$TC_DPV3":
+ case "$TC_DPV4":
+ case "$TC_DPV5":
+ case "$TC_DPNT":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ //// Clear tool
+ //tool
+ // .EdgesData[edgeIndex]
+ // .EdgeAdditionalParams
+ // .Clear();
+ // Get tool type additional parameters
+ if (toolEdgesConfig.EdgesConfig.ContainsKey(tool.ToolType))
+ {
+ // Find if actual param exist for the tool type
+ List toolTypeConfig = toolEdgesConfig.EdgesConfig[tool.ToolType];
+ EdgeConfigModel paramConfig = toolTypeConfig
+ .Where(x => x.Path == (GetStringUntilOrEmpty(actualString) + "["))
+ .FirstOrDefault();
+
+ // If Exist
+ if (paramConfig != null)
+ {
+ // Add additional param
+ tool
+ .EdgesData[edgeIndex]
+ .EdgeAdditionalParams
+ .Add(paramConfig.Name, Convert.ToDouble(actualString.Split('=').LastOrDefault(), numberFormat));
+ }
+ }
+ }
+ break;
+
+ case "$TC_DP25":
+ {
+ SiemensToolModel tool = ToolTableData[toolIndex];
+ // Sets tool value only with the first edge value
+ if (tool.EdgesData[edgeIndex].Id == 1)
+ {
+ // Get tool general information
+ var toolInfo = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+
+ // Convert rotation data
+ ROTATION rotation = ROTATION.NONE;
+ if (GetBitValue(toolInfo, 8))
+ rotation = ROTATION.CLOCKWHISE;
+ else if (GetBitValue(toolInfo, 9))
+ rotation = ROTATION.COUNTERCLOCKWHISE;
+ // Set new data
+
+ tool.Cooling1 = GetBitValue(toolInfo, 10);
+ tool.Cooling2 = GetBitValue(toolInfo, 11);
+ tool.Rotation = rotation;
+ }
+ }
+ break;
+
+ case "$TC_MPP1":
+ {
+ MagazinePositionsData.Add(new PositionModel()
+ {
+ PositionId = secondId,
+ MagazineId = firstId,
+ PhysicalType = (POSITION_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault())
+ });
+ }
+ break;
+
+ case "$TC_MPP2":
+ {
+ int index = MagazinePositionsData.FindIndex(x => x.PositionId == secondId && x.MagazineId == firstId);
+ if (index >= 0)
+ MagazinePositionsData[index].Type = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ //*SHANK FIX*MagazinePositionsData.Add(new PositionModel()
+ //{
+ // PositionId = secondId,
+ // MagazineId = firstId,
+ // Type = Convert.ToInt32(actualString.Split('=').LastOrDefault())
+ //});
+ }
+ break;
+
+ case "$TC_MPP4":
+ {
+ int index = MagazinePositionsData.FindIndex(x => x.PositionId == secondId && x.MagazineId == firstId);
+ if (index >= 0)
+ {
+ MagazinePositionsData[index].Disabled = GetBitValue(Convert.ToInt32(actualString.Split('=').LastOrDefault()), 0);
+ MagazinePositionsData[index].Occupied = GetBitValue(Convert.ToInt32(actualString.Split('=').LastOrDefault()), 2);
+ }
+ }
+ break;
+
+ case "$TC_MPP6":
+ {
+ int toolId = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ if (toolId != 0)
+ {
+ MoveToolInMagazineList(toolId, firstId, secondId);
+ }
+ }
+ break;
+
+ //*SHANK FIX*case "$TC_MTPP6":
+ // {
+ // // Find tool by id
+ // int toolId = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ // if (toolId != 0)
+ // {
+ // // Add new multitool child
+ // MultitoolsData[multitoolIndex].ChildsTools.Add(new ShankChildModel()
+ // {
+ // Id = toolId,
+ // MultitoolId = secondId
+ // });
+ // }
+ // }
+ // break;
+
+ case "$TC_MDP1":
+ {
+ // Add max number of magazine positions
+ SiemensMagazineConfigModel mag = MagazineConfig.Where(x => x.Id == firstId).FirstOrDefault();
+ if (mag != null)
+ mag.LoadPosition = secondId;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private SiemensToolModel CreateToolFromId(int toolIdToGet, string[] toolsStrings)
+ {
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+ SiemensToolModel outputTool = new SiemensToolModel();
+ int lastSecondId = 0;
+ int edgeIndex = 0;
+
+ // Foreach string
+ for (int i = 0; i < toolsStrings.Count(); i++)
+ {
+ string actualString = toolsStrings[i]; // Get actual string data
+
+ GetIdsFromSiemensToolString(actualString, out int firstId, out int secondId); // find ids from current string
+
+ if (firstId != 0 && firstId == toolIdToGet)
+ {
+ if (secondId == 0)
+ {
+ switch (GetStringUntilOrEmpty(actualString)) // Cut string until [ character
+ {
+ case "$TC_TP1":
+ {
+ outputTool = new SiemensToolModel()
+ {
+ Id = firstId,
+ ChildId = Convert.ToInt32(actualString.Split('=').LastOrDefault())
+ };
+ }
+ break;
+
+ case "$TC_TP2":
+ {
+ string familyName = actualString.Split('=').LastOrDefault().Replace("\"", "");
+ outputTool.FamilyName = familyName;
+ // Add new family with new tool
+ AddOrUpdateFamilyChild(familyName);
+ }
+ break;
+
+ case "$TC_TP3":
+ outputTool.LeftSize = Convert.ToByte(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP4":
+ outputTool.RightSize = Convert.ToByte(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP7":
+ outputTool.MagazinePositionType = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP8":
+ {
+ // Get tool status and read each bit
+ int toolStatus = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+
+ outputTool.IsActive = GetBitValue(toolStatus, 0);
+ outputTool.IsEnabled = GetBitValue(toolStatus, 1);
+ outputTool.IsInhibited = GetBitValue(toolStatus, 2);
+ outputTool.IsMeasured = GetBitValue(toolStatus, 3);
+ outputTool.PreAlarm = GetBitValue(toolStatus, 4);
+ outputTool.InChangeTool = GetBitValue(toolStatus, 5);
+ outputTool.InFixedPlace = GetBitValue(toolStatus, 6);
+ outputTool.IsInUse = GetBitValue(toolStatus, 7);
+ }
+ break;
+
+ case "$TC_TP9":
+ outputTool.LifeType = (SIEMENS_LIFE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ break;
+
+ case "$TC_TP_MAX_VELO":
+ outputTool.MaxSpeed = Convert.ToDouble(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ //case "$TC_TP_MAX_ACC":
+ // outputTool.MaxAcceleration = Convert.ToDouble(actualString.Split('=').LastOrDefault(), numberFormat);
+ // break;
+ // Custom CMS fields
+ case "$TC_TPC1":
+ outputTool.Load = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC2":
+ outputTool.Gamma = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC3":
+ outputTool.MaxLoadPctAutoload = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC4":
+ outputTool.MinLoadPctAutoload = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+
+ case "$TC_TPC5":
+ outputTool.ToolTypeCode = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat);
+ break;
+ }
+ }
+ else
+ {
+ // If secondId is changed, change current edge id
+ if (lastSecondId != secondId)
+ edgeIndex = outputTool.EdgesData.FindIndex(x => x.Id == secondId);
+
+ switch (GetStringUntilOrEmpty(actualString))
+ {
+ case "$TC_DP1":
+ {
+ if (secondId == 1) // Read tool type from first edge type
+ outputTool.ToolType = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+ // Add new edge
+ outputTool.EdgesData.Add(new EdgeModel() { Id = secondId });
+ edgeIndex = outputTool.EdgesData.Count - 1; // Update Index
+ }
+ break;
+
+ case "$TC_MOP1":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.TIME)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .PreAlmLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP2":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.TIME)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .ResidualLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP11":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.TIME)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .NominalLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP3":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.COUNT)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .PreAlmLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP4":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.COUNT)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .ResidualLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP13":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.COUNT)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .NominalLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP6":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.WEAR)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .ResidualLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP15":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.WEAR)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .NominalLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ case "$TC_MOP5":
+ {
+ if (outputTool.LifeType == SIEMENS_LIFE_TYPE.WEAR)
+ {
+ outputTool
+ .EdgesData[edgeIndex]
+ .PreAlmLife = Convert.ToDouble(actualString.Split('=').LastOrDefault());
+ }
+ }
+ break;
+
+ //case "$TC_DP2":
+ case "$TC_DP3":
+ case "$TC_DP4":
+ case "$TC_DP5":
+ case "$TC_DP6":
+ case "$TC_DP7":
+ case "$TC_DP8":
+ case "$TC_DP9":
+ case "$TC_DP10":
+ case "$TC_DP11":
+ case "$TC_DP12":
+ case "$TC_DP13":
+ case "$TC_DP14":
+ case "$TC_DP15":
+ case "$TC_DP16":
+ case "$TC_DP17":
+ case "$TC_DP21":
+ case "$TC_DP22":
+ case "$TC_DP23":
+ case "$TC_DP24":
+ case "$TC_DPV":
+ case "$TC_DPV3":
+ case "$TC_DPV4":
+ case "$TC_DPV5":
+ case "$TC_DPNT":
+ {
+ //// Clear tool
+ //outputTool
+ // .EdgesData[edgeIndex]
+ // .EdgeAdditionalParams
+ // .Clear();
+ // Get tool type additional parameters
+ if (toolEdgesConfig.EdgesConfig.ContainsKey(outputTool.ToolType))
+ {
+ // Find if actual param exist for the tool type
+ List toolTypeConfig = toolEdgesConfig.EdgesConfig[outputTool.ToolType];
+ EdgeConfigModel paramConfig = toolTypeConfig
+ .Where(x => x.Path == (GetStringUntilOrEmpty(actualString) + "["))
+ .FirstOrDefault();
+
+ // If Exist
+ if (paramConfig != null)
+ {
+ // Add additional param
+ outputTool
+ .EdgesData[edgeIndex]
+ .EdgeAdditionalParams
+ .Add(paramConfig.Name, Convert.ToDouble(actualString.Split('=').LastOrDefault(), numberFormat));
+ }
+ }
+ }
+ break;
+
+ case "$TC_DP25":
+ {
+ // Sets tool values with first edge value
+ if (outputTool.EdgesData[edgeIndex].Id == 1)
+ {
+ // Get tool general information
+ var toolInfo = Convert.ToInt32(actualString.Split('=').LastOrDefault());
+
+ // Convert rotation data
+ ROTATION rotation = ROTATION.NONE;
+ if (GetBitValue(toolInfo, 8))
+ rotation = ROTATION.CLOCKWHISE;
+ else if (GetBitValue(toolInfo, 9))
+ rotation = ROTATION.COUNTERCLOCKWHISE;
+ // Set new data
+
+ outputTool.Cooling1 = GetBitValue(toolInfo, 10);
+ outputTool.Cooling2 = GetBitValue(toolInfo, 11);
+ outputTool.Rotation = rotation;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return outputTool;
+ }
+
+ private EdgeModel SetUpEdgeData(string[] toolsString, SIEMENS_LIFE_TYPE lifeType, int toolId, int edgeId)
+ {
+ EdgeModel edgeData = new EdgeModel
+ {
+ Id = edgeId
+ };
+
+ switch (lifeType)
+ {
+ case SIEMENS_LIFE_TYPE.TIME:
+ {
+ edgeData.ResidualLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP2[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ edgeData.NominalLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP11[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ edgeData.PreAlmLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP1[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ }
+ break;
+
+ case SIEMENS_LIFE_TYPE.COUNT:
+ {
+ edgeData.ResidualLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP4[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ edgeData.NominalLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP13[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ edgeData.PreAlmLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP3[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ }
+ break;
+
+ case SIEMENS_LIFE_TYPE.WEAR:
+ {
+ // TODO: Check params
+ edgeData.ResidualLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP6[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ edgeData.NominalLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP15[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ edgeData.PreAlmLife = Convert.ToDouble(toolsString.FirstOrDefault(X => X.StartsWith("$TC_MOP5[" + toolId + "," + edgeId)).Split('=').LastOrDefault(), numberFormat);
+ }
+ break;
+ }
+
+ return edgeData;
+ }
+
+ private void ToolMngmtSvcHandler(Guid guid, ToolInfo[] toolInfos)
+ {
+ for (int i = 0; i < toolInfos.Count(); i++)
+ { // Choose behavior based on the actions5
+ ActionsHandler(toolInfos[i]);
+ }
+ }
+
+ private void ActionsHandler(ToolInfo toolInfo)
+ {
+ switch (toolInfo.action)
+ {
+ case ToolAction.TOOL_DELETED:
+ {
+ // Find tool
+ SiemensToolModel tool = ToolTableData.FirstOrDefault(t => t.Id == toolInfo.tNo);
+ if (tool != null)
+ {
+ // Delete Families
+ SiemensToolModel sameFamilyTool = ToolTableData.FirstOrDefault(x => x.FamilyName == tool.FamilyName && x.Id != tool.Id);
+ if (sameFamilyTool == null)
+ {
+ FamiliesData.RemoveAll(x => x.Name == tool.FamilyName);
+ }
+
+ // Dismount tool if is mounted in magazine
+ if (MagazineMountedTools.FirstOrDefault(x => x.ToolId == tool.Id) != null)
+ MoveToolInMagazineList(tool.Id, 0, 0);
+
+ // Remove
+ ToolTableData.Remove(tool);
+ }
+ //*SHANK FIX* else if (MULTITOOL_OPTION_ACTIVE)
+ // {
+ // // if tool not exist, find into shanks
+ // ShankModel shank = MultitoolsData.FirstOrDefault(t => t.Id == toolInfo.tNo);
+ // if (shank != null)
+ // try
+ // {
+ // Item item = new Item(string.Format("/Tool/MT/multitoolMyPlace[u1, {0}]", toolInfo.tNo));
+ // DataSvc dataSvc = new DataSvc();
+ // dataSvc.Read(item);
+ // }
+ // catch (Exception ex)
+ // {
+ // MultitoolsData.Remove(shank);
+ // }
+ // }
+ }
+ break;
+
+ case ToolAction.TOOL_CREATED:
+ {
+ string[] toolsStrings = ReadToolTableFile();
+
+ SiemensToolModel newTool = CreateToolFromId((int)toolInfo.tNo, toolsStrings);
+
+ if (newTool != null)
+ {
+ ToolTableData.Add(newTool);
+ AddOrUpdateFamilyChild(newTool.FamilyName);
+
+ // Read magazine id and position id from NC
+ DataSvc dataSvc = new DataSvc();
+ Item[] item = new Item[] {
+ new Item(){ Path = string.Format("/Tool/Data/toolInMag[{0}]", (int)toolInfo.tNo) },
+ new Item(){ Path = string.Format("/Tool/Data/toolInPlace[{0}]", toolInfo.tNo) }
+ };
+ dataSvc.Read(item);
+
+ int magazineId = Convert.ToInt32(item[0].Value);
+ int positionId = Convert.ToInt32(item[1].Value);
+
+ if (magazineId != 0 && positionId != 0)
+ MoveToolInMagazineList(newTool.Id, magazineId, positionId);
+ }
+ //*SHANK FIX*else if (MULTITOOL_OPTION_ACTIVE)
+ //{
+ // ShankModel newMultitool = CreateMultitoolFromId((int)toolInfo.tNo, toolsStrings);
+ // MultitoolsData.Add(newMultitool);
+ //}
+ }
+ break;
+
+ case ToolAction.TOOL_DATA_CHANGED:
+ {
+ string[] toolsStrings = ReadToolTableFile();
+
+ // Find edited toolIndex
+ int toolIndex = ToolTableData.FindIndex(t => t.Id == toolInfo.tNo);
+ // If the id belongs to a tool
+ if (toolIndex != -1)
+ {
+ // Get tool new data
+ SiemensToolModel newTool = CreateToolFromId((int)toolInfo.tNo, toolsStrings);
+
+ // *ASSISTED TOOLING FIX*
+ // After one reset in an assisted tooling procedure siemens send a "tool_data_changed" message
+ // Check if tool is not mounted and remove from magazine
+
+
+ // Read magazine id and position id from NC
+ DataSvc dataSvc = new DataSvc();
+ Item[] item = new Item[] {
+ new Item(){ Path = string.Format("/Tool/Data/toolInMag[{0}]", (int)toolInfo.tNo) },
+ new Item(){ Path = string.Format("/Tool/Data/toolInPlace[{0}]", toolInfo.tNo) }
+ };
+ dataSvc.Read(item);
+
+ int magazineId = Convert.ToInt32(item[0].Value);
+ int positionId = Convert.ToInt32(item[1].Value);
+
+ MoveToolInMagazineList(newTool.Id, magazineId, positionId);
+
+ // Replace the element
+ if (newTool != null)
+ ToolTableData[toolIndex] = newTool;
+ }
+
+ //*SHANK FIX*else if (MULTITOOL_OPTION_ACTIVE)
+ //{
+ // // Find if its a multitool
+ // int multitoolIndex = MultitoolsData.FindIndex(t => t.Id == toolInfo.tNo);
+
+ // if (multitoolIndex != -1)
+ // {
+ // // Create model with new data
+ // ShankModel newShank = CreateMultitoolFromId((int)toolInfo.tNo, toolsStrings);
+ // // Replace element
+ // if (newShank != null)
+ // MultitoolsData[multitoolIndex] = newShank;
+ // }
+ // else
+ // {
+ // ShankModel newMultitool = CreateMultitoolFromId((int)toolInfo.tNo, toolsStrings);
+ // MultitoolsData.Add(newMultitool);
+ // }
+ //}
+
+ Array.Clear(toolsStrings, 0, toolsStrings.Count());
+ }
+ break;
+
+ case ToolAction.TOOL_MOVED:
+ {
+ int magazineId = 0;
+ int positionId = 0;
+
+ var tool = GetToolOrMultitool(Convert.ToInt32(toolInfo.tNo));
+ if (tool is SiemensToolModel)
+ {
+ try
+ {
+ // Read magazine id and position id from NC
+ DataSvc dataSvc = new DataSvc();
+ Item[] item = new Item[] {
+ new Item(){ Path = string.Format("/Tool/Data/toolInMag[{0}]", (int)toolInfo.tNo) },
+ new Item(){ Path = string.Format("/Tool/Data/toolInPlace[{0}]", toolInfo.tNo) }
+ };
+ dataSvc.Read(item);
+
+ magazineId = Convert.ToInt32(item[0].Value);
+ positionId = Convert.ToInt32(item[1].Value);
+
+ }
+ catch (Exception ex)
+ {
+ magazineId = 0;
+ positionId = 0;
+ }
+ }
+
+ MoveToolInMagazineList((int)toolInfo.tNo, magazineId, positionId);
+
+ // moved MULTITOOL handler, add when Siemens Library bugs have been fixed
+ //*SHANK FIX*catch (Exception ex)
+ //{
+ // int shankIdx = MultitoolsData.FindIndex(x => x.Id == toolInfo.tNo);
+ // if (shankIdx < 0)
+ // {
+ // // Check that the move is inside a multitool
+ // item = new Item() { Path = string.Format("/Tool/Data/toolInMultitool[{0}]", toolInfo.tNo) };
+ // dataSvc.Read(item);
+ // // Check if readed multitool id exists
+ // int mtIndex = MultitoolsData.FindIndex(x => x.Id == Convert.ToInt32(item.Value));
+ // if (mtIndex >= 0)
+ // {
+ // int childIndex = MultitoolsData[mtIndex].ChildsTools.FindIndex(x => x.Id == toolInfo.tNo);
+ // if (childIndex < 0)
+ // {
+ // MultitoolsData[mtIndex].ChildsTools.Add(new ShankChildModel()
+ // {
+ // Id = Convert.ToInt32(toolInfo.tNo),
+ // MultitoolId = MultitoolsData[mtIndex].ChildsTools.Count + 1 // TODO ADD TOOL DATA OR REMOVE
+ // });
+ // }
+ // }
+ // }
+ //}
+ }
+ break;
+ }
+ }
+
+ private void MoveToolInMagazineList(int toolId, int magazineId, int positionId)
+ {
+ // If load magazine != 0, add new tool
+ if (magazineId != 0 && positionId != 0)
+ {
+ // Find tool by id
+ var tool = GetToolOrMultitool(toolId);
+ if (tool != null)
+ {
+ if (magazineId == 9998)
+ {
+ // Get old tool position
+ MountedToolModel toolMounted = MagazineMountedTools
+ .Where(x => x.ToolId == toolId)
+ .FirstOrDefault();
+
+ if (toolMounted != null)
+ {
+ // Set magazine position as occupied
+ var position = MagazinePositionsData.Where(x =>
+ x.MagazineId == toolMounted.MagazineId
+ && x.PositionId == toolMounted.PositionId)
+ .FirstOrDefault();
+
+ if (position != null)
+ position.Occupied = true;
+ }
+ }
+ else
+ {
+ // Free a position
+ var position = MagazinePositionsData.Where(x => x.MagazineId == magazineId && x.PositionId == positionId).FirstOrDefault();
+ if (position != null)
+ position.Occupied = false;
+ }
+
+ // Remove tool from list
+ MagazineMountedTools.RemoveAll(mountTool => PositionContainsTool(mountTool, toolId));
+
+ // Find if position exist
+ MountedToolModel mounted = MagazineMountedTools
+ .Where(x => x.MagazineId == magazineId && x.PositionId == positionId)
+ .FirstOrDefault();
+
+ if (mounted != null)
+ return;
+
+ // Add tool to list
+ MagazineMountedTools.Add(new MountedToolModel()
+ {
+ MagazineId = magazineId,
+ PositionId = positionId,
+ ToolId = toolId
+ });
+ }
+ }
+ else
+ {
+ // Remove tool from list
+ MagazineMountedTools.RemoveAll(mountTool => PositionContainsTool(mountTool, toolId));
+ }
+ }
+
+ private int GetLastToolId()
+ {
+ Item item = new Item()
+ {
+ Path = "/Tool/Catalogue/TnumWZV"
+ };
+
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(item);
+
+ return Convert.ToInt32(item.Value);
+
+ // First implementation before the path was found
+ //Get tool ids
+ //List toolIds = ToolTableData.Select(x => x.Id).ToList();
+ //// Sort tools ids array
+ //toolIds.Sort((x, y) => x.CompareTo(y));
+
+ //if (toolIds.Count == 0)
+ // return 1;
+
+ //for (int i = 0; i < toolIds.Count - 1; i++)
+ //{
+ // // If next id is different than previus + 1, there is an empty space in the array of numbers
+ // if (toolIds[i] + 1 != toolIds[i + 1])
+ // {
+ // // Check if the empty space is a multitool
+ // ShankModel shank = MultitoolsData.Where(x => x.Id == (toolIds[i] + 1)).FirstOrDefault();
+ // if (shank == null)
+ // {
+ // // return new id
+ // return toolIds[i] + 1;
+ // }
+ // }
+ //}
+ //// If there isn't an empty space return max id + 1
+ //return toolIds[toolIds.Count - 1] + 1;
+ }
+
+ private int GetLastMultitoolId()
+ {
+ Item item = new Item()
+ {
+ Path = "/Tool/MTCatalogue/MTnumWZV"
+ };
+
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(item);
+
+ return Convert.ToInt32(item.Value);
+ }
+
+ private int GetLastEdgeId(int toolId)
+ {
+ // Get edgeIds ids
+ List edgeIds = ToolTableData.Where(x => x.Id == toolId).FirstOrDefault()?.EdgesData.Select(x => x.Id).ToList();
+ // Sort tools ids array
+ edgeIds.Sort((x, y) => x.CompareTo(y));
+
+ if (edgeIds.Count == 0)
+ return 1;
+
+ for (int i = 0; i < edgeIds.Count - 1; i++)
+ {
+ // If next id is different than previus + 1, there is an empty space in the array of numbers
+ if (edgeIds[i] + 1 != edgeIds[i + 1])
+ {
+ // return new id
+ return edgeIds[i] + 1;
+ }
+ }
+
+ // If there isn't an empty space return max id + 1
+ return edgeIds[edgeIds.Count - 1] + 1;
+ }
+
+ private void AddOrUpdateFamilyChild(string familyName)
+ {
+ // Find family
+ int familyIndex = FamiliesData.FindIndex(x => x.Name == familyName);
+ if (familyIndex < 0)
+ {
+ // Create family and add child
+ FamiliesData.Add(new FamilyModel()
+ {
+ Name = familyName
+ });
+ }
+ }
+
+ private static void GetIdsFromSiemensToolString(string text, out int toolId, out int edgeId)
+ {
+ toolId = 0;
+ edgeId = 0;
+
+ if (!string.IsNullOrWhiteSpace(text))
+ {
+ // Get indexes from string
+ int startingData = text.IndexOf("[", StringComparison.Ordinal) + 1;
+ int secondData = text.IndexOf(",", StringComparison.Ordinal) + 1;
+ int endingData = text.IndexOf("]", StringComparison.Ordinal);
+ // If the string is matching with the pattern STRING[N]=N or STRING[N,M]=N
+ if (startingData > 0 && endingData > 0)
+ // STRING[N,M]=N case
+ if (secondData > 0)
+ {
+ toolId = Convert.ToInt32(text.Substring(startingData, secondData - (startingData + 1)));
+ edgeId = Convert.ToInt32(text.Substring(secondData, endingData - (secondData)));
+ }
+ else // STRING[N]=N case
+ {
+ toolId = Convert.ToInt32(text.Substring(startingData, endingData - (startingData)));
+ edgeId = 0;
+ }
+ }
+ }
+
+ #endregion Siemens Tool private functions
+
+ #region Multitool Private region
+
+ private void MultitoolsNumber_OnChange(Guid guid, Item item, DataSvcStatus status)
+ {
+ // Check if an element has been deleted
+ if ((uint)item.Value < multitoolsNumber)
+ {
+ // for each saved multitool
+ for (int i = 0; i < MultitoolsData.Count; i++)
+ {
+ try
+ {
+ // Check if exists
+ Item toolData = new Item(string.Format("/Tool/MT/multitoolMyPlace[u1, {0}]", MultitoolsData[i].Id));
+ DataSvc dataSvc = new DataSvc();
+ dataSvc.Read(toolData);
+ }
+ catch (Exception)
+ {
+ // Remove from list
+ MultitoolsData.RemoveAt(i);
+ }
+ }
+ }
+ // Update multitool counter
+ multitoolsNumber = (uint)item.Value;
+ }
+
+ private int ToolIsInMultitool(int toolId)
+ {
+ // Loop through multitools
+ //foreach (ShankModel multi in MultitoolsData)
+ //{
+ // if (multi.ChildsTools.Count() > 0)
+ // {
+ // // Find tool id in multitool childs
+ // int childIndex = multi.ChildsTools.FindIndex(x => x.Id == toolId);
+ // if (childIndex >= 0)
+ // return multi.Id;
+ // }
+ //}
+
+ return 0;
+ }
+
+ private CmsError CheckMultitoolData(ref ShankModel shank, bool isUpdate)
+ {
+ //Check if the NC is Connected
+ CmsError cmsError = CheckConnection();
+ if (cmsError.IsError())
+ return cmsError;
+
+ // Truncate name
+ if (shank.Name.Count() > 32)
+ shank.Name = shank.Name.Substring(0, 32);
+
+ int totalNumberOfChilds = 0;
+ foreach (ShankModel multi in MultitoolsData)
+ {
+ if (shank.Name == multi.Name && shank.Id != multi.Id)
+ return INCORRECT_PARAMETERS_ERROR;
+ // Calculate max number of childs
+ totalNumberOfChilds += multi.MaxChilds;
+ }
+
+ // Check if there are enough locations
+ if (!isUpdate && totalNumberOfChilds + MAX_TOOLS_PER_MULTITOOL > MAX_MULTITOOLS_LOCATIONS)
+ return MAX_MULTITOOL_LOCATION_REACHED_ERROR;
+
+ return NO_ERROR;
+ }
+
+ private ShankModel CreateMultitoolFromId(int multitoolId, string[] toolsStrings)
+ {
+ SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
+
+ // Find tool status status
+ var toolStatusByte = toolsStrings.FirstOrDefault(X => X.StartsWith("$TC_MTP8[" + multitoolId));
+ if (toolStatusByte == null)
+ return null;
+
+ int toolStatus = Convert.ToInt32(toolStatusByte.Split('=').LastOrDefault());
+
+ // Find shank, in order to get childs
+ ShankModel oldShank = MultitoolsData.Where(x => x.Id == multitoolId).FirstOrDefault();
+
+ // Create shank model
+ ShankModel shank = new ShankModel()
+ {
+ Id = multitoolId,
+ Name = toolsStrings.FirstOrDefault(x => x.Contains("$TC_MTP2[" + multitoolId)).Split('=').LastOrDefault().Replace("\"", ""),
+ LeftSize = Convert.ToByte(toolsStrings.FirstOrDefault(X => X.StartsWith("$TC_MTP3[" + multitoolId)).Split('=').LastOrDefault()),
+ RightSize = Convert.ToByte(toolsStrings.FirstOrDefault(X => X.StartsWith("$TC_MTP4[" + multitoolId)).Split('=').LastOrDefault()),
+ MagazinePositionType = Convert.ToByte(toolsStrings.FirstOrDefault(x => x.StartsWith("$TC_MTP7[" + multitoolId)).Split('=').LastOrDefault()),
+ MaxChilds = Convert.ToInt32(toolsStrings.FirstOrDefault(x => x.StartsWith("$TC_MTPN[" + multitoolId)).Split('=').LastOrDefault()),
+ IsEnabled = GetBitValue(toolStatus, 1),
+ IsInhibited = GetBitValue(toolStatus, 2),
+ InChangeTool = GetBitValue(toolStatus, 5),
+ InFixedPlace = GetBitValue(toolStatus, 6),
+ InUse = GetBitValue(toolStatus, 7),
+ ChildsTools = new List()
+ };
+
+ // Populate shank childs
+ for (int i = 1; i <= MAX_TOOLS_PER_MULTITOOL; i++)
+ {
+ // Find if position exists
+ var multitoolPos = toolsStrings.FirstOrDefault(x => x.Contains("$TC_MTPP6[" + multitoolId + "," + i));
+ if (multitoolPos != null)
+ {
+ // If not empty
+ int toolId = Convert.ToInt32(multitoolPos.Split('=').LastOrDefault());
+ if (toolId != 0)
+ {
+ shank.ChildsTools.Add(new ShankChildModel()
+ {
+ Id = toolId,
+ MultitoolId = i
+ });
+ }
+ }
+ }
+
+ // Check position in magazine
+ // Read magazine id from memory
+ DataSvc dataSvc = new DataSvc();
+ Item item = new Item() { Path = string.Format("/Tool/MT/multitoolInMag[{0}]", multitoolId) };
+ // Read magazine position
+ dataSvc.Read(item);
+ int magazineId = Convert.ToInt32(item.Value);
+ item = new Item() { Path = string.Format("/Tool/MT/multitoolInPlace[{0}]", multitoolId) };
+ dataSvc.Read(item);
+ int positionId = Convert.ToInt32(item.Value);
+
+ MoveToolInMagazineList(multitoolId, magazineId, positionId);
+
+ return shank;
+ }
+
+ #endregion Multitool Private region
+ }
+
+ internal static class MEMORY_ADDRESS
+ {
+ // aree Parametri
+
+ // aree Moduli
+
+ // riscaldi superiori
+
+ // riscaldi inferiori
+
+ // produzione
+
+ // ciclo produzione
+
+
+ internal const int TABLE = 258;
+
+ internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 1);
+ internal static MEMORY_CELL ACTIVE_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 1);
+
+ internal static MEMORY_CELL ACTIVE_CLIENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4, 1);
+
+ internal static MEMORY_CELL FUNCTION_ACCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6, 8);
+
+ internal static MEMORY_CELL PRE_POST_POWER_ON = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2574, 2);
+ internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2576, 2);
+ internal static MEMORY_CELL PRE_POST_POWER_ON_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2578, 2);
+ internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2580, 2);
+
+ internal static MEMORY_CELL AXIS_RESET_PROCEDURE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2608, 1);
+
+ internal static MEMORY_CELL PROCESS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2582, 24);
+ internal static MEMORY_CELL SELECTED_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2582, 24);
+ internal static MEMORY_CELL SELECT_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2606, 1);
+
+ internal static MEMORY_CELL COUNTERS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 40);
+
+ internal static MEMORY_CELL SELECTED_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2626, 1);
+ internal static MEMORY_CELL SELECT_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2627, 1);
+
+ internal static MEMORY_CELL NC_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2610, 4);
+ internal static MEMORY_CELL NC_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2614, 4);
+ internal static MEMORY_CELL NC_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2618, 4);
+ internal static MEMORY_CELL NC_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2622, 4);
+
+ internal static MEMORY_CELL USER_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2628, 16);
+ internal static MEMORY_CELL USER_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2644, 16);
+ internal static MEMORY_CELL USER_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2660, 16);
+ internal static MEMORY_CELL USER_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2676, 16);
+
+ internal static MEMORY_CELL ALARMS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 14, 128);
+ internal static MEMORY_CELL ALARMS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 142, 1024);
+
+ internal static MEMORY_CELL ALARM_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2190, 128);
+ internal static MEMORY_CELL ALARM_RESTORATION_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2318, 128);
+ internal static MEMORY_CELL ALARM_REFRESH_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2446, 128);
+
+ internal static MEMORY_CELL HEADS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2692, 240);
+
+ internal static MEMORY_CELL HEADS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2932, 4);
+ internal static MEMORY_CELL HEADS_STROBE_INCREMENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2936, 4);
+ internal static MEMORY_CELL HEADS_STROBE_DECREMENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2940, 4);
+
+ internal static MEMORY_CELL COUNTERS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2944, 64);
+ internal static MEMORY_CELL COUNTER_IS_RESETTABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3008, 2);
+ internal static MEMORY_CELL COUNTER_IS_RESETTABLE_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3010, 2);
+ internal static MEMORY_CELL COUNTER_IS_RESETTABLE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3012, 2);
+
+ internal static MEMORY_CELL M155_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3014, 1);
+ internal static MEMORY_CELL M155_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3015, 1);
+ internal static MEMORY_CELL M155_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3016, 1);
+
+ internal static MEMORY_CELL M156_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4333, 1);
+ internal static MEMORY_CELL M156_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4335, 1);
+ internal static MEMORY_CELL M156_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4337, 1);
+ internal static MEMORY_CELL M156_INPUT_ID_LIST = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4339, 8);
+
+ internal static MEMORY_CELL M154_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3042, 1);
+ internal static MEMORY_CELL M154_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3043, 1);
+ internal static MEMORY_CELL M154_SWITCH_ONOFF = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
+
+ internal static MEMORY_CELL AXES_BUTTON_VISIBLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3044, 16);
+
+ internal static MEMORY_CELL MAGAZINE_ACTION = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4000, 16);
+
+ internal static MEMORY_CELL BALLUF_ACTION_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4014, 1);
+ internal static MEMORY_CELL BALLUF_ACTION_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4015, 1);
+ internal static MEMORY_CELL BALLUF_ACTION_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4016, 1);
+
+ //old CMS-Control variables
+ internal static MEMORY_CELL HEADS_WORKED_TIMES = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 254, 60, 4);
+ internal static MEMORY_CELL HEAD_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 92, 4);
+ internal static MEMORY_CELL MACHINE_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 94, 4);
+ internal static MEMORY_CELL MACHINE_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 98, 4);
+ internal static MEMORY_CELL CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 130, 1);
+ internal static MEMORY_CELL EXP_CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 92, 1);
+
+
+ internal static MEMORY_CELL SELF_ADAPTIVE_PATH = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 253, 16, 4);
+
+ internal static MEMORY_CELL BALLUF_EMPTY_TABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 111, 0, 486);
+
+ // Machine number
+ internal static MEMORY_CELL MATR_MACCH_SIEMENS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 0, 1);
+ internal static MEMORY_CELL NEW_MATR_MACC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 258, 3060, 4);
+ }
+}
\ No newline at end of file