diff --git a/CMS_CORE_Library/CMS_CORE_Library.csproj b/CMS_CORE_Library/CMS_CORE_Library.csproj index 976b9aa..506fb62 100644 --- a/CMS_CORE_Library/CMS_CORE_Library.csproj +++ b/CMS_CORE_Library/CMS_CORE_Library.csproj @@ -103,8 +103,8 @@ False libs\CndexLinkDotNet.dll - - ..\..\..\..\..\Workspace\CMS_CORE_LIBRARY\CMS_CORE_Application\bin\x86\Debug\S7.Net.dll + + ..\packages\S7netplus.0.8.1\lib\net452\S7.Net.dll False diff --git a/CMS_CORE_Library/Demo/Nc_Demo.cs b/CMS_CORE_Library/Demo/Nc_Demo.cs index 475c721..8256a2d 100644 --- a/CMS_CORE_Library/Demo/Nc_Demo.cs +++ b/CMS_CORE_Library/Demo/Nc_Demo.cs @@ -27,6 +27,7 @@ namespace CMS_CORE_Library.Demo private DemoEdgesConfiguration DemoEdgesConfiguration = new DemoEdgesConfiguration(); private const string PART_PROGRAM_FOLDER = "C:/CMS/Active/DEMO/part_program/"; private const string JOB_PROGRAM_FOLDER = PART_PROGRAM_FOLDER + "\\job\\"; + private Random rand = new Random(); // Magazine config parameters private List MagazineConfig = new List() @@ -1142,6 +1143,12 @@ namespace CMS_CORE_Library.Demo return NO_ERROR; } + public override CmsError PROC_RFeed(ushort ProcNumber, ref float Feed) + { + Feed = Convert.ToSingle(rand.NextDouble() * 100); + return NO_ERROR; + } + private CmsError ResetStrobe(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType) { int n = 5; @@ -1419,6 +1426,7 @@ namespace CMS_CORE_Library.Demo // Populate response structure processData.Type = bits[3] ? "AUX" : "WORK"; processData.CanLoadProgram = bits[6]; + processData.IsInPieceWork = rand.NextDouble() > 0.5f; // Choose process status if (bits[4]) diff --git a/CMS_CORE_Library/Fanuc/Nc_Fanuc.cs b/CMS_CORE_Library/Fanuc/Nc_Fanuc.cs index ae4c85a..35a19d9 100644 --- a/CMS_CORE_Library/Fanuc/Nc_Fanuc.cs +++ b/CMS_CORE_Library/Fanuc/Nc_Fanuc.cs @@ -1620,6 +1620,7 @@ namespace CMS_CORE_Library.Fanuc // Get process part program data public override CmsError PROC_RStatusAndData(ushort procNumber, ref ProcessDataModel processData) { + Boolean Cut = false; processData.Id = procNumber; // Read part program name CmsError cmsError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName); @@ -1632,6 +1633,15 @@ namespace CMS_CORE_Library.Fanuc if (cmsError.IsError()) return cmsError; + //Read CUT variable + byte CutRaw = 0; + int address = (1000 * (procNumber - 1)) + 2; + cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Fanuc_F, address, 0, ref CutRaw); + if (cmsError.IsError()) + return cmsError; + + Cut = (CutRaw & 0x40) == 0x40; + byte[] bytes = BitConverter.GetBytes(readValue); // Convert Byte into true/false array @@ -1645,6 +1655,7 @@ namespace CMS_CORE_Library.Fanuc processData.IsSelected = bits[2]; processData.IsInAlarm = bits[3]; processData.CanLoadProgram = bits[4]; + processData.IsInPieceWork = Cut; // Choose process status if (bytes[1] == 1) @@ -2009,6 +2020,28 @@ namespace CMS_CORE_Library.Fanuc return NO_ERROR; } + + + public override CmsError PROC_RFeed(ushort ProcNumber, ref float Feed) + { + CmsError cmsError = CheckConnection(); + if (cmsError.IsError()) + return cmsError; + + if (ProcNumber <= 0) + return PROC_NOT_FOUND_ERROR; + + + ODBACT feedRaw = new ODBACT(); + short nReturn = Focas1.cnc_actf(nLibHandle[ProcNumber - 1], feedRaw); + // Check return value + if (nReturn != 0) + return GetNcError(nReturn); + + Feed = feedRaw.data / 10.0f; + return NO_ERROR; + } + #endregion PROCESS (PATH) High-level data /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/CMS_CORE_Library/Models/DataStructures.cs b/CMS_CORE_Library/Models/DataStructures.cs index d063401..494f1e4 100644 --- a/CMS_CORE_Library/Models/DataStructures.cs +++ b/CMS_CORE_Library/Models/DataStructures.cs @@ -86,7 +86,8 @@ namespace CMS_CORE_Library.Models LOADING = 2, UNLOADING = 3, EXCHANGE = 5, - START_NEEDED = 7 + START_NEEDED = 7, + TOOL_MANAGER_ERROR = 99 } public enum SIEMENS_MAGAZINE_TYPE @@ -285,6 +286,7 @@ namespace CMS_CORE_Library.Models public bool Visible; public ushort Reps; public bool IsSelected; + public bool IsInPieceWork; public bool CanLoadProgram; } diff --git a/CMS_CORE_Library/Models/ThermoModels.cs b/CMS_CORE_Library/Models/ThermoModels.cs index a23afcb..78745ad 100644 --- a/CMS_CORE_Library/Models/ThermoModels.cs +++ b/CMS_CORE_Library/Models/ThermoModels.cs @@ -219,7 +219,7 @@ namespace CMS_CORE_Library.Models return false; if (EstimatedDuration != item.EstimatedDuration) return false; - if (PrecedingId != item.PrecedingId) + if (!PrecedingId.Equals(PrecedingId)) return false; if (Visible != item.Visible) return false; @@ -387,6 +387,119 @@ namespace CMS_CORE_Library.Models } + /// + /// Represent IO Channel visibility + /// + public class ChanIOVis + { + public Dictionary DI { get; set; } = new Dictionary(); + public Dictionary DO { get; set; } = new Dictionary(); + public Dictionary AI { get; set; } = new Dictionary(); + public Dictionary AO { get; set; } = new Dictionary(); + + public override bool Equals(object obj) + { + if (!(obj is ChanIOVis item)) + return false; + + if (!DI.Equals(item.DI)) + return false; + if (!DO.Equals(item.DO)) + return false; + if (!AI.Equals(item.AI)) + return false; + if (!AO.Equals(item.AO)) + return false; + + return true; + } + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + /// + /// Represent IO Channel Values + /// + public class ChanIOVal + { + public Dictionary DI { get; set; } = new Dictionary(); + public Dictionary DO { get; set; } = new Dictionary(); + public Dictionary AI { get; set; } = new Dictionary(); + public Dictionary AO { get; set; } = new Dictionary(); + + public override bool Equals(object obj) + { + if (!(obj is ChanIOVal item)) + return false; + + if (!DI.Equals(item.DI)) + return false; + if (!DO.Equals(item.DO)) + return false; + if (!AI.Equals(item.AI)) + return false; + if (!AO.Equals(item.AO)) + return false; + + return true; + } + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + /// + /// Represent IO Channel FORCED by UI + /// + public class ChanIOFor + { + public Dictionary DO { get; set; } = new Dictionary(); + public Dictionary AO { get; set; } = new Dictionary(); + + public override bool Equals(object obj) + { + if (!(obj is ChanIOVis item)) + return false; + + if (!DO.Equals(item.DO)) + return false; + if (!AO.Equals(item.AO)) + return false; + + return true; + } + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + /// + /// Represent IO Channel FORCED values + /// + public class ChanIOValFor + { + public Dictionary DO { get; set; } = new Dictionary(); + public Dictionary AO { get; set; } = new Dictionary(); + + public override bool Equals(object obj) + { + if (!(obj is ChanIOVal item)) + return false; + + if (!DO.Equals(item.DO)) + return false; + if (!AO.Equals(item.AO)) + return false; + + return true; + } + public override int GetHashCode() + { + return base.GetHashCode(); + } + } + /// /// Recipe Parameters /// diff --git a/CMS_CORE_Library/Nc.cs b/CMS_CORE_Library/Nc.cs index 0ec7c00..e638892 100644 --- a/CMS_CORE_Library/Nc.cs +++ b/CMS_CORE_Library/Nc.cs @@ -775,6 +775,20 @@ namespace CMS_CORE_Library public abstract CmsError PLC_WTerminateAssistedToolingProcedure(); + /** + * + * Read the actual feed of the Process "ProcNumber" + * + * Compatibility: Fanuc | Osai | Demo | Siemens + * + * + * Returns an error when an internal or a library error occours + * Process number which the data refer + * Feed of the Process in mm/min + * */ + + public abstract CmsError PROC_RFeed(ushort ProcNumber, ref float Feed); + #endregion PROCESS (PATH, CHANNEL) data (to override) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/CMS_CORE_Library/NcThermo.cs b/CMS_CORE_Library/NcThermo.cs index 616dbd7..515864d 100644 --- a/CMS_CORE_Library/NcThermo.cs +++ b/CMS_CORE_Library/NcThermo.cs @@ -796,6 +796,15 @@ namespace CMS_CORE_Library /// 1: MAN, 2: AUTO, 3: SETUP /// public abstract CmsError PLC_WModeSel(int mode); + /// + /// Read PLC current IO hannels data + /// + /// updates only VALUE readout + /// Visibility status for all channels + /// Values for channels + /// Indicates if values are forced by UI + /// Values forced by UI + public abstract CmsError PLC_RIOChannels(bool onlyVal, ref ThermoModels.ChanIOVis currThermoIOVis, ref ThermoModels.ChanIOVal currThermoIOVal, ref ThermoModels.ChanIOFor currThermoIOFor, ref ThermoModels.ChanIOValFor currThermoIOValFor); #endregion THERMO high level data diff --git a/CMS_CORE_Library/Osai/Nc_Osai.cs b/CMS_CORE_Library/Osai/Nc_Osai.cs index bf827c0..6aa332a 100644 --- a/CMS_CORE_Library/Osai/Nc_Osai.cs +++ b/CMS_CORE_Library/Osai/Nc_Osai.cs @@ -1954,9 +1954,18 @@ namespace CMS_CORE_Library.Osai cmsError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address + ((procNumber - 1) * 2), ref readValue); if (cmsError.IsError()) return cmsError; - byte[] bytes = BitConverter.GetBytes(readValue); + + // Read processes status from memory + int index = (20 * procNumber) + 2; + ushort readWord = 0; + bool isInPiece = false; + cmsError = MEM_RWWord(R, 0, MEMORY_TYPE.Osai_SW, PROCESS_STATUS.Address + ((procNumber - 1) * 2), ref readWord); + if (cmsError.IsError()) + return cmsError; + isInPiece = (readWord & 0x1) != 0x1; //Bit 1 + // 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 @@ -1968,6 +1977,7 @@ namespace CMS_CORE_Library.Osai processData.IsSelected = bits[2]; processData.IsInAlarm = bits[3]; processData.CanLoadProgram = bits[4]; + processData.IsInPieceWork = isInPiece; // Choose process status if (bytes[1] == 1) @@ -2095,6 +2105,17 @@ namespace CMS_CORE_Library.Osai } + + public override CmsError PROC_RFeed(ushort ProcNumber, ref float Feed) + { + ushort nReturn = OpenNC.GetNcInfo1((ushort)ProcNumber, out GETINFO1DATA info, out uint errorClass, out uint errorNum); + if (errorClass != 0 || errorNum != 0 || nReturn == 0) + return GetNCError(errorClass, errorNum); + + Feed = Convert.ToSingle(info.realfeed); + return NO_ERROR; + } + #endregion PROCESS (PATH) High-level data /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs index 1050442..d167384 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -62,6 +62,10 @@ namespace CMS_CORE_Library.S7Net private static ThermoModels.ProdInfoModel ThermoProdInfo = new ThermoModels.ProdInfoModel(); private static ThermoModels.ProdCycleModel ThermoProdCycle = new ThermoModels.ProdCycleModel(); private static ThermoModels.ThermoCam ThermoCamData = new ThermoModels.ThermoCam(); + private static ThermoModels.ChanIOVis ThermoIOVis = new ThermoModels.ChanIOVis(); + private static ThermoModels.ChanIOVal ThermoIOVal = new ThermoModels.ChanIOVal(); + private static ThermoModels.ChanIOFor ThermoIOFor = new ThermoModels.ChanIOFor(); + private static ThermoModels.ChanIOValFor ThermoIOValFor = new ThermoModels.ChanIOValFor(); // connessione S7 private CpuType tipoCpu = CpuType.S71500; @@ -2597,6 +2601,7 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } + /// /// Refresh recipE parameters RT @@ -3731,6 +3736,284 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } + /// + /// Read PLC current IO hannels data + /// + /// updates only RT parameters (false = update all) + /// Visibility status for all channels + /// Values for channels + /// Indicates if values are forced by UI + /// Values forced by UI + /// + public override CmsError PLC_RIOChannels(bool onlyVal, ref ThermoModels.ChanIOVis currThermoIOVis, ref ThermoModels.ChanIOVal currThermoIOVal, ref ThermoModels.ChanIOFor currThermoIOFor, ref ThermoModels.ChanIOValFor currThermoIOValFor) + { + CmsError currError = NO_ERROR; + // refresh dati veloci (valori) + refreshChIOVal(); + // se richiesto NON SOLO RT faccio refresh anche dati "lenti" + if (!onlyVal) + { + refreshChIOVisib(); + refreshChIOForced(); + refreshChIOForcedVal(); + } + + // copio liste in output... + currThermoIOVis = ThermoIOVis; + currThermoIOVal = ThermoIOVal; + currThermoIOFor = ThermoIOFor; + currThermoIOValFor = ThermoIOValFor; + + // esco + return currError; + } + + /// + /// Refresh IO channels actual value + /// + /// + protected CmsError refreshChIOVal() + { + CmsError libraryError = NO_ERROR; +#if false + List currMem = new List(); + int packSize = 8; + + // leggo da PLC a array di byte di appoggio... + libraryError = MEM_RWByteList(R, 0, PARAMETER_RT_DATA.MemType, PARAMETER_RT_DATA.Address, PARAMETER_RT_DATA.SubAddress, 0, PARAMETER_RT_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < PARAMETER_RT_DATA.Size / packSize; i++) + { + PlcParamRT currParam = new PlcParamRT(memArray.Skip(i * packSize).Take(packSize).ToArray()); + // solo se ID > 0... + if (currParam.Id > 0) + { + // update oggetto thermoParamList... + if (ThermoParamList.ContainsKey(currParam.Id)) + { + try + { + ThermoParamList[currParam.Id].Enabled = currParam.Enabled; + ThermoParamList[currParam.Id].HasError = currParam.HasError; + ThermoParamList[currParam.Id].Visible = currParam.Visible; + ThermoParamList[currParam.Id].ValueAct = currParam.ValueAct; + } + catch + { } + } + else + { + try + { + ThermoParamList.Add(currParam.Id, new ThermoModels.RecipeParam() { Id = currParam.Id, Enabled = currParam.Enabled, HasError = currParam.HasError, Visible = currParam.Visible, ValueAct = currParam.ValueAct }); + } + catch + { } + } + } + } + } +#endif + + return libraryError; + } + + /// + /// Refresh recipe parameters + /// + protected CmsError refreshChIOVisib() + { + CmsError libraryError = NO_ERROR; + Byte[] byteArray = null; + List readValuesDI = new List(); + List readValuesDO = new List(); + List readValuesAI = new List(); + List readValuesAO = new List(); + + // leggo da PLC a array di byte di appoggio x visibilità DI... + libraryError = MEM_RWWordList(R, 0, IO_DI_VISIB.MemType, IO_DI_VISIB.Address, IO_DI_VISIB.SubAddress, IO_DI_VISIB.Size, ref readValuesDI); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC a array di byte di appoggio x visibilità DO... + libraryError = MEM_RWWordList(R, 0, IO_DO_VISIB.MemType, IO_DO_VISIB.Address, IO_DO_VISIB.SubAddress, IO_DO_VISIB.Size, ref readValuesDO); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC a array di byte di appoggio x visibilità AI... + libraryError = MEM_RWWordList(R, 0, IO_AI_VISIB.MemType, IO_AI_VISIB.Address, IO_AI_VISIB.SubAddress, IO_AI_VISIB.Size, ref readValuesAI); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC a array di byte di appoggio x visibilità AO... + libraryError = MEM_RWWordList(R, 0, IO_AO_VISIB.MemType, IO_AO_VISIB.Address, IO_AO_VISIB.SubAddress, IO_AO_VISIB.Size, ref readValuesAO); + if (libraryError.IsError()) + return libraryError; + + ThermoIOVis.DI = convShortToDict(readValuesDI); + ThermoIOVis.DO = convShortToDict(readValuesDO); + ThermoIOVis.AI = convShortToDict(readValuesAI); + ThermoIOVis.AO = convShortToDict(readValuesAO); + + return libraryError; + } + + internal static Dictionary convShortToDict(List origVal) + { + Byte[] byteArray = null; + // Convert List into Byte Array + byteArray = origVal.SelectMany(j => BitConverter.GetBytes(j)).ToArray(); + // converto a bit + BitArray bitArr = new BitArray(byteArray); + Dictionary answ = new Dictionary(); + for (int i = 0; i < bitArr.Count; i++) + { + answ.Add(i, bitArr[i]); + } + return answ; + } + + /// + /// Refresh recipe parameters + /// + protected CmsError refreshChIOForcedVal() + { + CmsError libraryError = NO_ERROR; +#if false + List currMem = new List(); + int packSize = 20; + + // leggo da PLC a array di byte di appoggio... + libraryError = MEM_RWByteList(R, 0, PARAMETER_DATA.MemType, PARAMETER_DATA.Address, PARAMETER_DATA.SubAddress, 0, PARAMETER_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + + for (int i = 0; i < PARAMETER_DATA.Size / packSize; i++) + { + PlcParam currParam = new PlcParam(memArray.Skip(i * packSize).Take(packSize).ToArray()); + // solo se ID > 0... + if (currParam.Id > 0) + { + // update oggetto thermoParamList... + if (ThermoParamList.ContainsKey(currParam.Id)) + { + try + { + ThermoParamList[currParam.Id].SetpointHMI = currParam.SetpointHMI; + ThermoParamList[currParam.Id].SetpointPLC = currParam.SetpointPLC; + ThermoParamList[currParam.Id].ValMax = currParam.ValMax; + ThermoParamList[currParam.Id].ValMin = currParam.ValMin; + ThermoParamList[currParam.Id].UnitMeasure = currParam.UnitMeasure; + } + catch + { } + } + else + { + try + { + ThermoParamList.Add(currParam.Id, new ThermoModels.RecipeParam() { Id = currParam.Id, SetpointHMI = currParam.SetpointHMI, SetpointPLC = currParam.SetpointPLC, ValMax = currParam.ValMax, ValMin = currParam.ValMin, UnitMeasure = currParam.UnitMeasure }); + } + catch + { } + } + } + else + { + libraryError = S7_PLC_WRONG_DATA; + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } +#endif + + + return libraryError; + } + /// + /// Refresh recipe parameters + /// + protected CmsError refreshChIOForced() + { + CmsError libraryError = NO_ERROR; +#if false + List currMem = new List(); + int packSize = 20; + + // leggo da PLC a array di byte di appoggio... + libraryError = MEM_RWByteList(R, 0, PARAMETER_DATA.MemType, PARAMETER_DATA.Address, PARAMETER_DATA.SubAddress, 0, PARAMETER_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + + for (int i = 0; i < PARAMETER_DATA.Size / packSize; i++) + { + PlcParam currParam = new PlcParam(memArray.Skip(i * packSize).Take(packSize).ToArray()); + // solo se ID > 0... + if (currParam.Id > 0) + { + // update oggetto thermoParamList... + if (ThermoParamList.ContainsKey(currParam.Id)) + { + try + { + ThermoParamList[currParam.Id].SetpointHMI = currParam.SetpointHMI; + ThermoParamList[currParam.Id].SetpointPLC = currParam.SetpointPLC; + ThermoParamList[currParam.Id].ValMax = currParam.ValMax; + ThermoParamList[currParam.Id].ValMin = currParam.ValMin; + ThermoParamList[currParam.Id].UnitMeasure = currParam.UnitMeasure; + } + catch + { } + } + else + { + try + { + ThermoParamList.Add(currParam.Id, new ThermoModels.RecipeParam() { Id = currParam.Id, SetpointHMI = currParam.SetpointHMI, SetpointPLC = currParam.SetpointPLC, ValMax = currParam.ValMax, ValMin = currParam.ValMin, UnitMeasure = currParam.UnitMeasure }); + } + catch + { } + } + } + else + { + libraryError = S7_PLC_WRONG_DATA; + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } +#endif + + + return libraryError; + } + #endregion /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -5306,6 +5589,22 @@ namespace CMS_CORE_Library.S7Net internal static MEMORY_CELL RISC_OVP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 10752, 1024); internal static MEMORY_CELL RISC_ICH_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 11776, 4096); + // gestione canali IO + internal static MEMORY_CELL IO_STATW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 0, 2); + internal static MEMORY_CELL IO_COMMW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 2, 2); + internal static MEMORY_CELL IO_DI_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 4, 64); + internal static MEMORY_CELL IO_DO_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 68, 64); + internal static MEMORY_CELL IO_AI_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 132, 64); + internal static MEMORY_CELL IO_AO_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 196, 64); + internal static MEMORY_CELL IO_DI_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 260, 64); + internal static MEMORY_CELL IO_DO_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 324, 64); + internal static MEMORY_CELL IO_AI_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 388, 4); + internal static MEMORY_CELL IO_AO_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 392, 4); + internal static MEMORY_CELL IO_DO_FORCE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 396, 64); + internal static MEMORY_CELL IO_DO_VAL_FOR = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 460, 64); + internal static MEMORY_CELL IO_AO_FORCE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 524, 4); + internal static MEMORY_CELL IO_AO_VAL_FOR = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 528, 64); + // ThermoCamera internal static MEMORY_CELL TCAM_STATW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 0, 2); internal static MEMORY_CELL TCAM_COMMW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 2, 2); diff --git a/CMS_CORE_Library/Siemens/Nc_Siemens.cs b/CMS_CORE_Library/Siemens/Nc_Siemens.cs index 5100064..1f915e9 100644 --- a/CMS_CORE_Library/Siemens/Nc_Siemens.cs +++ b/CMS_CORE_Library/Siemens/Nc_Siemens.cs @@ -58,6 +58,7 @@ namespace CMS_CORE_Library.Siemens // 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"; + private const string LOCALE_TOOL_ERR_PATH = "C:\\CMS\\Active\\TMP\\TOOLS_ERR.LOG"; // Global Variables private static DateTime Last_Static_Read; @@ -71,6 +72,7 @@ namespace CMS_CORE_Library.Siemens private static uint MaxChannelNo; private static uint SiemensLanguage; private static string UnitOfMeasure; + private static Boolean ErrorDuringToolsReading; // Alarms data private static AlarmSvc SiemensAlmSvc = null; @@ -2327,6 +2329,7 @@ namespace CMS_CORE_Library.Siemens processData.IsSelected = bits[2]; processData.IsInAlarm = bits[3]; processData.CanLoadProgram = bits[4]; + processData.IsInPieceWork = false; // Choose process status if (bytes[1] == 1) @@ -2516,6 +2519,28 @@ namespace CMS_CORE_Library.Siemens return NO_ERROR; } + + + public override CmsError PROC_RFeed(ushort ProcNumber, ref float Feed) + { + if (ProcNumber <= 0) + return PROC_NOT_FOUND_ERROR; + try + { + Item item = new Item { Path = "/Channel/State/actFeedRateIpo[u" + ProcNumber + ", 1]" }; + // Read data + DataSvc dataSvc = new DataSvc(); + dataSvc.Read(item); + Feed = Convert.ToSingle(item.Value); + } + catch (Exception ex) + { + return ManageException(ex); + } + + return NO_ERROR; + } + private CmsError PROC_ReadActiveLine(uint processId, ref string line) { try @@ -5119,6 +5144,24 @@ namespace CMS_CORE_Library.Siemens public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction) { + //To test it + /* + if (ErrorDuringToolsReading) + { + magazineAction = new MagazineActionModel() + { + Action = MAGAZINE_ACTIONS.TOOL_MANAGER_ERROR, + Tool = null, + SecondTool = null, + OriginMagazine = 0, + OriginPosition = 0, + DestinationMagazine = 0, + DestinationPosition = 0 + }; + return NO_ERROR; + } + */ + magazineAction = MagazineAction; return NO_ERROR; } @@ -5747,7 +5790,7 @@ namespace CMS_CORE_Library.Siemens } } - private void PopulateToolsTableFromFileStrings(string[] toolsStrings) + public void PopulateToolsTableFromFileStrings(string[] toolsStrings) { SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration(); @@ -5755,6 +5798,7 @@ namespace CMS_CORE_Library.Siemens int lastSecondId = 0; int toolIndex = 0; int edgeIndex = 0; + ErrorDuringToolsReading = true; // int multitoolIndex = 0; // Foreach string @@ -5783,7 +5827,7 @@ namespace CMS_CORE_Library.Siemens ToolTableData.Add(new SiemensToolModel() { Id = firstId, - ChildId = Convert.ToInt32(actualString.Split('=').LastOrDefault()) + ChildId = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()) }); // Update Index toolIndex = ToolTableData.Count - 1; @@ -5808,13 +5852,13 @@ namespace CMS_CORE_Library.Siemens break; case "$TC_TP7": - ToolTableData[toolIndex].MagazinePositionType = Convert.ToInt32(actualString.Split('=').LastOrDefault()); + ToolTableData[toolIndex].MagazinePositionType = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; case "$TC_TP8": { // Get tool status and read each bit - int toolStatus = Convert.ToInt32(actualString.Split('=').LastOrDefault()); + int toolStatus = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); ToolTableData[toolIndex].IsActive = GetBitValue(toolStatus, 0); ToolTableData[toolIndex].IsEnabled = GetBitValue(toolStatus, 1); @@ -5828,7 +5872,7 @@ namespace CMS_CORE_Library.Siemens break; case "$TC_TP9": - ToolTableData[toolIndex].LifeType = (SIEMENS_LIFE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault()); + ToolTableData[toolIndex].LifeType = (SIEMENS_LIFE_TYPE)ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; case "$TC_TP_MAX_VELO": @@ -5840,23 +5884,23 @@ namespace CMS_CORE_Library.Siemens // break; // Custom CMS fields case "$TC_TPC1": - ToolTableData[toolIndex].Load = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat); + ToolTableData[toolIndex].Load = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; case "$TC_TPC2": - ToolTableData[toolIndex].Gamma = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat); + ToolTableData[toolIndex].Gamma = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; case "$TC_TPC3": - ToolTableData[toolIndex].MaxLoadPctAutoload = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat); + ToolTableData[toolIndex].MaxLoadPctAutoload = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; case "$TC_TPC4": - ToolTableData[toolIndex].MinLoadPctAutoload = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat); + ToolTableData[toolIndex].MinLoadPctAutoload = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; case "$TC_TPC5": - ToolTableData[toolIndex].ToolTypeCode = Convert.ToInt32(actualString.Split('=').LastOrDefault(), numberFormat); + ToolTableData[toolIndex].ToolTypeCode = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); break; //*SHANK FIX*case "$TC_MTPN": @@ -5908,19 +5952,19 @@ namespace CMS_CORE_Library.Siemens if (mag == null) { bool active = true; - SIEMENS_MAGAZINE_TYPE type = (SIEMENS_MAGAZINE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault()); + SIEMENS_MAGAZINE_TYPE type = (SIEMENS_MAGAZINE_TYPE)ConvertToSiemensInt32(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()), + Type = (SIEMENS_MAGAZINE_TYPE)ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()), LoadingIsActive = active }); } else - mag.Type = (SIEMENS_MAGAZINE_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault()); + mag.Type = (SIEMENS_MAGAZINE_TYPE)ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); } break; @@ -5938,7 +5982,7 @@ namespace CMS_CORE_Library.Siemens // 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()); + mag.MaxPositions = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); } break; } @@ -5954,7 +5998,7 @@ namespace CMS_CORE_Library.Siemens case "$TC_DP1": { if (secondId == 1) // Read tool type from first edge type - ToolTableData[toolIndex].ToolType = Convert.ToInt32(actualString.Split('=').LastOrDefault()); + ToolTableData[toolIndex].ToolType = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); // Add new edge ToolTableData[toolIndex].EdgesData.Add(new EdgeModel() { Id = secondId }); edgeIndex = ToolTableData[toolIndex].EdgesData.Count - 1; // Update Index @@ -6130,7 +6174,7 @@ namespace CMS_CORE_Library.Siemens if (tool.EdgesData[edgeIndex].Id == 1) { // Get tool general information - var toolInfo = Convert.ToInt32(actualString.Split('=').LastOrDefault()); + var toolInfo = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); // Convert rotation data ROTATION rotation = ROTATION.NONE; @@ -6153,7 +6197,7 @@ namespace CMS_CORE_Library.Siemens { PositionId = secondId, MagazineId = firstId, - PhysicalType = (POSITION_TYPE)Convert.ToInt32(actualString.Split('=').LastOrDefault()) + PhysicalType = (POSITION_TYPE)ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()) }); } break; @@ -6162,7 +6206,7 @@ namespace CMS_CORE_Library.Siemens { int index = MagazinePositionsData.FindIndex(x => x.PositionId == secondId && x.MagazineId == firstId); if (index >= 0) - MagazinePositionsData[index].Type = Convert.ToInt32(actualString.Split('=').LastOrDefault()); + MagazinePositionsData[index].Type = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); //*SHANK FIX*MagazinePositionsData.Add(new PositionModel() //{ // PositionId = secondId, @@ -6177,15 +6221,15 @@ namespace CMS_CORE_Library.Siemens 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); + MagazinePositionsData[index].Disabled = GetBitValue(ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()), 0); + MagazinePositionsData[index].Occupied = GetBitValue(ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()), 2); } } break; case "$TC_MPP6": { - int toolId = Convert.ToInt32(actualString.Split('=').LastOrDefault()); + int toolId = ConvertToSiemensInt32(actualString.Split('=').LastOrDefault()); if (toolId != 0) { MoveToolInMagazineList(toolId, firstId, secondId); @@ -6945,6 +6989,32 @@ namespace CMS_CORE_Library.Siemens } } + private int ConvertToSiemensInt32(string str) + { + //Replace with Standard Exponent + String intr = str.Replace("EX", "E"); + + //Convert + if(!float.TryParse(intr, NumberStyles.Float, CultureInfo.InvariantCulture, out float number)) + { + using (StreamWriter w = File.AppendText(LOCALE_TOOL_ERR_PATH)) + w.WriteLine($"{DateTime.Now.ToString("yyyy_MM_dd:hh_mm_ss")}\t\tERR: Read incorrect format while parsing: {str}"); + + ErrorDuringToolsReading = true; + return Int32.MaxValue; + } + + //Check error + if (Math.Abs(number % 1) > (Double.Epsilon * 100)) + { + ErrorDuringToolsReading = true; + using (StreamWriter w = File.AppendText(LOCALE_TOOL_ERR_PATH)) + w.WriteLine($"{DateTime.Now.ToString("yyyy_MM_dd:hh_mm_ss")}\t\tERR: Read Float and not Int value: {str}"); + } + + return (int) Math.Floor(number); + } + #endregion Siemens Tool private functions #region Multitool Private region diff --git a/CMS_CORE_Library/Utils/Nc_Utils.cs b/CMS_CORE_Library/Utils/Nc_Utils.cs index 3515087..c12d8ff 100644 --- a/CMS_CORE_Library/Utils/Nc_Utils.cs +++ b/CMS_CORE_Library/Utils/Nc_Utils.cs @@ -203,7 +203,7 @@ namespace CMS_CORE_Library.Utils .Cast() .ToArray(); } - + // Convert a byte into an array of bools public static bool[] ByteToBits(byte val) { diff --git a/CMS_CORE_Library/packages.config b/CMS_CORE_Library/packages.config index ed7aa38..5fb683d 100644 --- a/CMS_CORE_Library/packages.config +++ b/CMS_CORE_Library/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file