diff --git a/CMS_CORE_Library/Models/ThermoModels.cs b/CMS_CORE_Library/Models/ThermoModels.cs index 78745ad..08cef20 100644 --- a/CMS_CORE_Library/Models/ThermoModels.cs +++ b/CMS_CORE_Library/Models/ThermoModels.cs @@ -6,22 +6,20 @@ namespace CMS_CORE_Library.Models { public class ThermoModels { - - #region Fields + #region Protected Fields protected const double EPSILON = 0.1; - #endregion Fields + #endregion Protected Fields - #region Classes + #region Public Classes /// /// Single AXIS Info Data /// public class AxisInfo { - - #region Properties + #region Public Properties public int ControlWord { get; set; } = 0; public int ErrorCode { get; set; } = 0; @@ -30,9 +28,9 @@ namespace CMS_CORE_Library.Models public int StatusWord { get; set; } = 0; public double TargetPos { get; set; } = 0; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods public override bool Equals(object obj) { @@ -54,13 +52,13 @@ namespace CMS_CORE_Library.Models return false; return true; } + public override int GetHashCode() { return base.GetHashCode(); } - #endregion Methods - + #endregion Public Methods } /// @@ -68,8 +66,7 @@ namespace CMS_CORE_Library.Models /// public class AxisRT { - - #region Constructors + #region Public Constructors /// /// Deserializzazione da byte ad oggetto AxisRT @@ -84,18 +81,18 @@ namespace CMS_CORE_Library.Models Load = S7.Net.Types.Double.FromByteArray(rawData.Skip(8).Take(4).ToArray()); } - #endregion Constructors + #endregion Public Constructors - #region Properties + #region Public Properties public int Id { get; set; } = 0; public double Load { get; set; } = 0; public double Position { get; set; } = 0; public double Speed { get; set; } = 0; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods /// /// Converte un singolo item in un array di byte per scrittura su PLC S7 @@ -126,13 +123,165 @@ namespace CMS_CORE_Library.Models return false; return true; } + public override int GetHashCode() { return base.GetHashCode(); } - #endregion Methods + #endregion Public Methods + } + /// + /// Represent IO Channel FORCED by UI + /// + public class ChanIOFor + { + #region Public Properties + + public Dictionary AO { get; set; } = new Dictionary(); + public Dictionary DO { get; set; } = new Dictionary(); + + #endregion Public Properties + + #region Public Methods + + 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(); + } + + #endregion Public Methods + } + + /// + /// Represent IO Channel Values + /// + public class ChanIOVal + { + #region Public Properties + + public Dictionary AI { get; set; } = new Dictionary(); + public Dictionary AO { get; set; } = new Dictionary(); + public Dictionary DI { get; set; } = new Dictionary(); + public Dictionary DO { get; set; } = new Dictionary(); + + #endregion Public Properties + + #region Public Methods + + 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(); + } + + #endregion Public Methods + } + + /// + /// Represent IO Channel FORCED values + /// + public class ChanIOValFor + { + #region Public Properties + + public Dictionary AO { get; set; } = new Dictionary(); + public Dictionary DO { get; set; } = new Dictionary(); + + #endregion Public Properties + + #region Public Methods + + 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(); + } + + #endregion Public Methods + } + + /// + /// Represent IO Channel visibility + /// + public class ChanIOVis + { + #region Public Properties + + public Dictionary AI { get; set; } = new Dictionary(); + public Dictionary AO { get; set; } = new Dictionary(); + public Dictionary DI { get; set; } = new Dictionary(); + public Dictionary DO { get; set; } = new Dictionary(); + + #endregion Public Properties + + #region Public Methods + + 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(); + } + + #endregion Public Methods } /// @@ -140,17 +289,16 @@ namespace CMS_CORE_Library.Models /// public class LiveProdDataModel { - - #region Properties + #region Public Properties public double Air { get; set; } = 0; public double Power { get; set; } = 0; public double TimeAdv { get; set; } = 0; public double Vacuum { get; set; } = 0; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods public override bool Equals(object obj) { @@ -178,15 +326,85 @@ namespace CMS_CORE_Library.Models return base.GetHashCode(); } - #endregion Methods - + #endregion Public Methods } + public class LogCycleData + { + #region Public Constructors + + /// + /// Deserializzazione da byte ad oggetto LogCycleData + /// + /// + public LogCycleData(byte[] rawData) + { + // converto i dati da byte grezzi ai 3 componenti... + year = S7.Net.Types.Word.FromByteArray(rawData.Skip(0).Take(2).ToArray()); + month = S7.Net.Types.Byte.FromByteArray(rawData.Skip(2).Take(1).ToArray()); + day = S7.Net.Types.Byte.FromByteArray(rawData.Skip(3).Take(1).ToArray()); + hour = S7.Net.Types.Byte.FromByteArray(rawData.Skip(4).Take(1).ToArray()); + min = S7.Net.Types.Byte.FromByteArray(rawData.Skip(5).Take(1).ToArray()); + msec = S7.Net.Types.Word.FromByteArray(rawData.Skip(6).Take(2).ToArray()); + Code = S7.Net.Types.Word.FromByteArray(rawData.Skip(8).Take(2).ToArray()); + } + + #endregion Public Constructors + + #region Public Properties + + protected int year { get; set; } = 0; + protected int month { get; set; } = 0; + protected int day { get; set; } = 0; + protected int hour { get; set; } = 0; + protected int min { get; set; } = 0; + protected int msec { get; set; } = 0; + public DateTime DtEvent + { + get + { + DateTime answ = DateTime.Now; + try + { + new DateTime(year, month, day); + answ = answ.AddHours(hour).AddMinutes(min).AddMilliseconds(msec); + } + catch + { } + return answ; + } + } + public int Code { get; set; } = 0; + + #endregion Public Properties + + #region Public Methods + + + public override bool Equals(object obj) + { + // Object is not a GaugeModel instance + if (!(obj is LogCycleData item)) + return false; + + if (DtEvent != item.DtEvent) + return false; + if (Code != item.Code) + return false; + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion Public Methods + } public class ModuleBlock { - - #region Properties + #region Public Properties public int ActualDelay { get; set; } = 0; public int ActualDuration { get; set; } = 0; @@ -199,9 +417,9 @@ namespace CMS_CORE_Library.Models public bool Terminated { get; set; } = false; public bool Visible { get; set; } = false; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods public override bool Equals(object obj) { @@ -232,19 +450,18 @@ namespace CMS_CORE_Library.Models return true; } + public override int GetHashCode() { return base.GetHashCode(); } - #endregion Methods - + #endregion Public Methods } public class ProdCycleModel { - - #region Properties + #region Public Properties public ushort MessageId { get; set; } = 0; public ushort Mode { get; set; } = 0; @@ -252,9 +469,9 @@ namespace CMS_CORE_Library.Models public ushort Submode { get; set; } = 0; public uint TimeAdv { get; set; } = 0; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods public override bool Equals(object obj) { @@ -275,41 +492,41 @@ namespace CMS_CORE_Library.Models return true; } + public override int GetHashCode() { return base.GetHashCode(); } - #endregion Methods - + #endregion Public Methods } public class ProdInfoModel { - - #region Properties + #region Public Properties public DateTime DtEvent { get; set; } = DateTime.Now; public bool IsScrap { get; set; } = false; - public double MaterialTempEndVent { get; set; } = 0; - public double MaterialTempEndWarm { get; set; } = 0; - public double MoldTemp { get; set; } = 0; - public double MouldEnergyIN { get; set; } = 0; - public double MouldEnergyOUT { get; set; } = 0; + public float MaterialTempEndVent { get; set; } = 0; + public float MaterialTempEndWarm { get; set; } = 0; + public float MoldTemp { get; set; } = 0; + public float MouldEnergyIN { get; set; } = 0; + public float MouldEnergyOUT { get; set; } = 0; public short NumDone { get; set; } = 0; public short NumPreHot { get; set; } = 0; public short NumTarget { get; set; } = 0; public short PreWarmCycle { get; set; } = 0; + public string ThermoImage { get; set; } = ""; public int TimeCycleGross { get; set; } = 0; public int TimeCycleNet { get; set; } = 0; public int TimeVacuum { get; set; } = 0; public int TimeVent { get; set; } = 0; public int TimeWarm { get; set; } = 0; - public double VacuumReadVal { get; set; } = 0; + public float VacuumReadVal { get; set; } = 0; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods /// /// Converte un singolo item in un array di byte per scrittura su PLC S7 @@ -326,12 +543,12 @@ namespace CMS_CORE_Library.Models Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(TimeVacuum), 0, answ, 14, 4); Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(TimeCycleGross), 0, answ, 18, 4); Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(TimeCycleNet), 0, answ, 22, 4); - Buffer.BlockCopy(S7.Net.Types.Double.ToByteArray(MaterialTempEndWarm), 0, answ, 26, 4); - Buffer.BlockCopy(S7.Net.Types.Double.ToByteArray(MaterialTempEndVent), 0, answ, 30, 4); - Buffer.BlockCopy(S7.Net.Types.Double.ToByteArray(MoldTemp), 0, answ, 34, 4); - Buffer.BlockCopy(S7.Net.Types.Double.ToByteArray(VacuumReadVal), 0, answ, 38, 4); - Buffer.BlockCopy(S7.Net.Types.Double.ToByteArray(MouldEnergyOUT), 0, answ, 42, 4); - Buffer.BlockCopy(S7.Net.Types.Double.ToByteArray(MouldEnergyIN), 0, answ, 46, 4); + Buffer.BlockCopy(S7.Net.Types.Real.ToByteArray(MaterialTempEndWarm), 0, answ, 26, 4); + Buffer.BlockCopy(S7.Net.Types.Real.ToByteArray(MaterialTempEndVent), 0, answ, 30, 4); + Buffer.BlockCopy(S7.Net.Types.Real.ToByteArray(MoldTemp), 0, answ, 34, 4); + Buffer.BlockCopy(S7.Net.Types.Real.ToByteArray(VacuumReadVal), 0, answ, 38, 4); + Buffer.BlockCopy(S7.Net.Types.Real.ToByteArray(MouldEnergyOUT), 0, answ, 42, 4); + Buffer.BlockCopy(S7.Net.Types.Real.ToByteArray(MouldEnergyIN), 0, answ, 46, 4); return answ; } @@ -349,6 +566,8 @@ namespace CMS_CORE_Library.Models return false; if (PreWarmCycle != item.PreWarmCycle) return false; + if (ThermoImage != item.ThermoImage) + return false; if (TimeWarm != item.TimeWarm) return false; if (TimeVent != item.TimeVent) @@ -378,126 +597,13 @@ namespace CMS_CORE_Library.Models return true; } + public override int GetHashCode() { return base.GetHashCode(); } - #endregion Methods - - } - - /// - /// 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(); - } + #endregion Public Methods } /// @@ -505,8 +611,7 @@ namespace CMS_CORE_Library.Models /// public class RecipeParam { - - #region Properties + #region Public Properties public bool Enabled { get; set; } = false; public bool HasError { get; set; } = false; @@ -520,9 +625,9 @@ namespace CMS_CORE_Library.Models public double ValueAct { get; set; } = 0; public bool Visible { get; set; } = false; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods public override bool Equals(object obj) { @@ -555,39 +660,46 @@ namespace CMS_CORE_Library.Models return true; } + public override int GetHashCode() { return base.GetHashCode(); } - #endregion Methods - + #endregion Public Methods } + /// /// ThermoCam management data /// public class ThermoCam { - /// - /// Opzione ThermoCamera (set by PLC) - /// - public bool ThermoOptionActive { get; set; } = false; + #region Public Properties + /// /// Modalità ThermoCamera (set by HMI) /// public bool ThermoCamMode { get; set; } = false; + /// /// Funzionamento ThermoCamera (set by HMI) /// public bool ThermoCamOnOff { get; set; } = false; + + /// + /// Opzione ThermoCamera (set by PLC) + /// + public bool ThermoOptionActive { get; set; } = false; + + #endregion Public Properties } + /// /// Warmers channel data /// public class WarmerChannel { - - #region Properties + #region Public Properties /// /// Channel status @@ -644,9 +756,9 @@ namespace CMS_CORE_Library.Models /// public short TCamTempSet { get; set; } = 0; - #endregion Properties + #endregion Public Properties - #region Methods + #region Public Methods /// /// Equality test for class object @@ -690,11 +802,9 @@ namespace CMS_CORE_Library.Models return base.GetHashCode(); } - #endregion Methods - + #endregion Public Methods } - #endregion Classes - + #endregion Public Classes } -} +} \ No newline at end of file diff --git a/CMS_CORE_Library/NcThermo.cs b/CMS_CORE_Library/NcThermo.cs index 515864d..e3e75fb 100644 --- a/CMS_CORE_Library/NcThermo.cs +++ b/CMS_CORE_Library/NcThermo.cs @@ -636,6 +636,13 @@ namespace CMS_CORE_Library /// public abstract CmsError PLC_WAckSetpointInvalidated(); + /// + /// Get current LOG Cycle data + /// + /// + /// + public abstract CmsError PLC_RLogCycleData(out List currLogCycle); + /// /// Get current Axis RT data /// @@ -669,6 +676,17 @@ namespace CMS_CORE_Library /// true: HMI --> PLC, false: PLC --> HMI /// public abstract CmsError PLC_WRecipeEdit(bool confirmUpdate); + + /// + /// Send axis command + /// + /// ID asse + /// Comando (0..15) + /// Indica se scrivere la TargetPos + /// Posizione target + /// + public abstract CmsError PLC_WAxisCommand(int AxisNum, uint CommandBit, bool WritePos, double TargetPos); + /// /// Confirm FLIR image acquired and copied to PLC /// @@ -797,14 +815,54 @@ namespace CMS_CORE_Library /// public abstract CmsError PLC_WModeSel(int mode); /// - /// Read PLC current IO hannels data + /// Read PLC current IO Channels visibility (conf) /// - /// updates only VALUE readout /// Visibility status for all channels + public abstract CmsError PLC_RIOChannelsConf(ref ThermoModels.ChanIOVis currThermoIOVis); + /// + /// Read PLC current IO Channels VALUES (actual + forced) + /// /// 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); + public abstract CmsError PLC_RIOChannelsVal(ref ThermoModels.ChanIOVal currThermoIOVal, ref ThermoModels.ChanIOFor currThermoIOFor, ref ThermoModels.ChanIOValFor currThermoIOValFor); + /// + /// Write MULTIPLE Digital Out values (+ force) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public abstract CmsError PLC_W_IO_DO_Val(Dictionary newValues); + /// + /// Write MULTIPLE Analog Out values (+ force) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public abstract CmsError PLC_W_IO_AO_Val(Dictionary newValues); + /// + /// Reset MULTIPLE Digital Out FORCED Status (bitmap) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public abstract CmsError PLC_W_IO_DO_Reset(Dictionary newValues); + /// + /// Reset MULTIPLE Digital Out FORCED Status (bitmap) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public abstract CmsError PLC_W_IO_AO_Reset(Dictionary newValues); + /// + /// Reset ALL DO / AO forced bitmap + /// + /// + public abstract CmsError PLC_W_IO_ResetAll(); #endregion THERMO high level data diff --git a/CMS_CORE_Library/S7Net/Nc_S7Net.cs b/CMS_CORE_Library/S7Net/Nc_S7Net.cs index d167384..1dd52e5 100644 --- a/CMS_CORE_Library/S7Net/Nc_S7Net.cs +++ b/CMS_CORE_Library/S7Net/Nc_S7Net.cs @@ -18,74 +18,317 @@ using static CMS_CORE_Library.Utils.Nc_Utils; namespace CMS_CORE_Library.S7Net { + internal static class MEMORY_ADDRESS + { + // A) THERMO SPECIAL MEMORY + + #region Internal Fields + + // Main DB Table + internal const int TABLE = 604; + + // B) GEN memory (NOT Thermo) + internal static MEMORY_CELL ACTIVE_CLIENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4, 1); + + internal static MEMORY_CELL ALARM_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2190, 128); + + internal static MEMORY_CELL ALARM_REFRESH_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2318, 128); + + internal static MEMORY_CELL ALARM_RESTORATION_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2318, 128); + + internal static MEMORY_CELL ALARMS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 142, 1024); + + internal static MEMORY_CELL ALARMS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 14, 128); + + // assi + internal static MEMORY_CELL AXES_BUTTON_VISIBLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3044, 16); + + internal static MEMORY_CELL AXES_COMMAND = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 512, 512); + + internal static MEMORY_CELL AXES_INFO = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 0, 512); + + internal static MEMORY_CELL AXES_RTDATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 615, 0, 768); + + internal static MEMORY_CELL AXIS_RESET_PROCEDURE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2608, 1); + + internal static MEMORY_CELL CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 130, 1); + + 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 COUNTERS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 40); + + internal static MEMORY_CELL COUNTERS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2944, 64); + + internal static MEMORY_CELL EXP_CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 92, 1); + + internal static MEMORY_CELL FIRMWARE_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6764, 4); + + internal static MEMORY_CELL FUNCTION_ACCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6, 8); + + internal static MEMORY_CELL HEAD_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 92, 4); + + //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 IO_AI_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 132, 64); + + internal static MEMORY_CELL IO_AI_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 388, 4); + + internal static MEMORY_CELL IO_AO_FORCE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 524, 4); + + internal static MEMORY_CELL IO_AO_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 196, 64); + + internal static MEMORY_CELL IO_AO_VAL_FOR = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 528, 64); + + internal static MEMORY_CELL IO_AO_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 392, 4); + + 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_DI_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 260, 64); + + internal static MEMORY_CELL IO_DO_FORCE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 396, 64); + + internal static MEMORY_CELL IO_DO_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 68, 64); + + internal static MEMORY_CELL IO_DO_VAL_FOR = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 460, 64); + + internal static MEMORY_CELL IO_DO_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 324, 64); + + // gestione canali IO + internal static MEMORY_CELL IO_STATW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 0, 2); + + internal static MEMORY_CELL KEYBOARD_STAR_MEMORY = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6780, 2); + + internal static MEMORY_CELL LOG_CYCLE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 617, 12, 1000); + + 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 M156_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6770, 1); + + internal static MEMORY_CELL M156_INPUT_ID_LIST = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6774, 2); + + internal static MEMORY_CELL M156_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6768, 1); + + //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 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_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6772, 1); + + //internal static MEMORY_CELL HEADS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2692, 240); + internal static MEMORY_CELL M156_RESPONSE_MEMORY = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6776, 4); + + // generic machine gauge data + internal static MEMORY_CELL MACHINE_GAUGE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 6, 16); + + internal static MEMORY_CELL MACHINE_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 98, 4); + + internal static MEMORY_CELL MACHINE_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 94, 4); + + internal static MEMORY_CELL MAGAZINE_ACTION = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4000, 16); + + // aree Moduli + internal static MEMORY_CELL MODULE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 602, 18, 2304); + + internal static MEMORY_CELL MODULE_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 603, 12, 1536); + + 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 NC_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2614, 4); + + internal static MEMORY_CELL NC_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2610, 4); + + // watchdog + internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 1); + + internal static MEMORY_CELL NEW_MATR_MACC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 4); + + // aree Parametri + internal static MEMORY_CELL PARAMETER_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 600, 20, 8000); + + // recipe edit confirmation/cancel strobe/ack + internal static MEMORY_CELL PARAMETER_EDIT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); + + internal static MEMORY_CELL PARAMETER_EDIT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + internal static MEMORY_CELL PARAMETER_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 601, 8, 3200); + internal static MEMORY_CELL PRE_POST_POWER_ON = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6542, 4); + + // C) STD MEM (need check!) FIXME TODO + 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 PROCESS_PROD_CYCLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 22); + + // produzione + internal static MEMORY_CELL PROCESS_PROD_INFO = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 606, 0, 52); + + internal static MEMORY_CELL PROCESS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 2); + + // Prod strobe/ack + internal static MEMORY_CELL PROD_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); + + internal static MEMORY_CELL PROD_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + + internal static MEMORY_CELL REQ_CONF_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + + // strobe received from PLC + internal static MEMORY_CELL REQ_CONF_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); + + // Mode request strobe/ack + internal static MEMORY_CELL REQ_MODE_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); + + internal static MEMORY_CELL REQ_MODE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); + internal static MEMORY_CELL RISC_CFI_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 2176, 1024); + + // riscaldi + internal static MEMORY_CELL RISC_CHP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 614, 0, 1024); + + internal static MEMORY_CELL RISC_ESP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 9728, 1024); + + internal static MEMORY_CELL RISC_ICH_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 11776, 4096); + + internal static MEMORY_CELL RISC_ICH_MIN_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 3200, 4096); + + internal static MEMORY_CELL RISC_OCC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 64, 64); + + internal static MEMORY_CELL RISC_OCS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 9472, 64); + + internal static MEMORY_CELL RISC_OVP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 10752, 1024); + + internal static MEMORY_CELL RISC_PLC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 627, 0, 1024); + + internal static MEMORY_CELL RISC_VU_MIN = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 513, 0, 2); + + internal static MEMORY_CELL SELECT_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2627, 1); + + internal static MEMORY_CELL SELECT_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2606, 1); + + internal static MEMORY_CELL SELECTED_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2626, 1); + + internal static MEMORY_CELL SELECTED_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2582, 24); + + internal static MEMORY_CELL SER_NUM_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6746, 22); + + // Machine data + internal static MEMORY_CELL STATIC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 48); + + // status/command data + internal static MEMORY_CELL STATUS_CMD_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 4); + + internal static MEMORY_CELL TCAM_CH_ENAB_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 4, 128); + + internal static MEMORY_CELL TCAM_COMMW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 2, 2); + + //internal static MEMORY_CELL RISC_PLC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 128, 1024); //valore PRE thermoCam + // ThermoCamera + internal static MEMORY_CELL TCAM_STATW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 0, 2); + + internal static MEMORY_CELL TCAM_TEMP_ACT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 625, 0, 2048); + internal static MEMORY_CELL TCAM_TEMP_REQ_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 624, 0, 2048); + + internal static MEMORY_CELL USER_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6584, 16); + internal static MEMORY_CELL USER_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6600, 16); + internal static MEMORY_CELL USER_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6568, 16); + internal static MEMORY_CELL USER_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6552, 16); + internal static MEMORY_CELL VERS_SW_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6724, 22); + + #endregion Internal Fields + + //internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2576, 2); + } + public class Nc_S7Net : NcThermo { - - #region costanti ed oggetti // Global Constants + #region Private Fields + private const string NcNotFound = "Missing response"; private const string NcNotFound2 = "networking error"; private const string NcNotFound3 = "Nc not Connected"; - // Global Variables - private static DateTime Last_Static_Read; - - private byte S7Language; - private static string Cnc_name; - private static string Cnc_SftVersion; - private static string Cnc_SeriesNum; - private static string Cms_MachNumber; - private static string PlcFirmware_SerialNum; - private static uint ConfChannelNo; - private static string UnitOfMeasure; - - // Alarms data - private static Dictionary PlcMessages = new Dictionary(); private const string THERMO_DICT_PATH = @"Dict\"; - private static ushort SelectedProcess = 1; - - private bool EnableAlarms; - private bool EnableHeaters; - private bool EnableModules; - private bool EnableParameters; - private bool EnableProd; - - private bool EnableAxes; - - - // Dizionario parametri specifici per THERMO - private static Dictionary ThermoParamList = new Dictionary(); - private static Dictionary ThermoModuleList = new Dictionary(); - private static Dictionary ThermoWarmChannels = new Dictionary(); - 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; - private short rack = 0; - private short slot = 1; - - /// - /// Oggetto PLC da ri-utilizzare... - /// - protected Plc currPLC; /// /// Lock per connessione PLC /// private readonly static object connectLock = new object(); - #endregion + private static string Cms_MachNumber; + + private static string Cnc_name; + + private static string Cnc_SeriesNum; + + private static string Cnc_SftVersion; + + private static uint ConfChannelNo; + + // Global Variables + private static DateTime Last_Static_Read; + + private static string PlcFirmware_SerialNum; + + // Alarms data + private static Dictionary PlcMessages = new Dictionary(); + + private static ushort SelectedProcess = 1; + private static ThermoModels.ThermoCam ThermoCamData = new ThermoModels.ThermoCam(); + private static ThermoModels.ChanIOFor ThermoIOFor = new ThermoModels.ChanIOFor(); + private static ThermoModels.ChanIOVal ThermoIOVal = new ThermoModels.ChanIOVal(); + private static ThermoModels.ChanIOValFor ThermoIOValFor = new ThermoModels.ChanIOValFor(); + private static ThermoModels.ChanIOVis ThermoIOVis = new ThermoModels.ChanIOVis(); + private static Dictionary ThermoModuleList = new Dictionary(); + + // Dizionario parametri specifici per THERMO + private static Dictionary ThermoParamList = new Dictionary(); + + private static ThermoModels.ProdCycleModel ThermoProdCycle = new ThermoModels.ProdCycleModel(); + private static ThermoModels.ProdInfoModel ThermoProdInfo = new ThermoModels.ProdInfoModel(); + private static Dictionary ThermoWarmChannels = new Dictionary(); + private static string UnitOfMeasure; + private bool EnableAlarms; + private bool EnableAxes; + private bool EnableHeaters; + private bool EnableModules; + private bool EnableParameters; + private bool EnableProd; + private short rack = 0; + private byte S7Language; + private short slot = 1; + + // connessione S7 + private CpuType tipoCpu = CpuType.S71500; + + #endregion Private Fields + + #region Protected Fields + + /// + /// Oggetto PLC da ri-utilizzare... + /// + protected Plc currPLC; + + #endregion Protected Fields /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #region Constructor & global methods + #region Public Constructors /// ///Instantiate The NC-S7Net Class @@ -97,6 +340,7 @@ namespace CMS_CORE_Library.S7Net { initObjects(IpAddress, RemotePort, false, true, true, true, true, true); } + /// /// Instantiate The NC-Siemens Class /// @@ -113,6 +357,233 @@ namespace CMS_CORE_Library.S7Net { initObjects(IpAddress, RemotePort, EnableAxes, EnableAlarms, EnableHeaters, EnableModules, EnableParameters, EnableProd); } + + #endregion Public Constructors + + #region Private Methods + + private Dictionary AXES_RAxesPos(ushort channel, string positionType) + { + Dictionary axes = new Dictionary(); + return axes; + } + + 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; + } + + //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 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; + } + + // 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; + } + } + + 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 ""; + } + } + + //Convert to Step Language + private string ConvertToNCLanguage(CultureInfo language) + { + return language.ThreeLetterISOLanguageName; + } + + //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"); + } + } + + //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; + } + + private string FormatPath(string path) + { + path = path.TrimStart('\\'); + path = path.TrimStart('/'); + path = path.TrimEnd('\\'); + + return path.Replace('\\', '/'); + } + + // Create and return CmsError object + private CmsError GetError(string message) + { + return CmsError.NcError(message); + } + + private IEnumerable GetLinesFromString(string text) + { + string line; + using (StringReader reader = new StringReader(text)) + { + while ((line = reader.ReadLine()) != null) + { + yield return line; + } + } + } + + // 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; + } + /// /// /Inizializzazione effettiva parametri classe /// @@ -140,8 +611,2017 @@ namespace CMS_CORE_Library.S7Net // mesasggi generici PLC PlcMessages = new Dictionary(); // Init dati specifici Thermo - } + + //Manage the Exception Launch + private CmsError ManageException(Exception ex) + { + // Catch the S7Net exceptions + 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 + { + return CmsError.InternalError(ex.Message, ex); + } + } + + private void NcLanguageChanged(string language) + { + } + + private CmsError PLC_ManageActiveAck(int strobeByte, int strobeSubByte, int strobeBit, int ackByte, int ackSubByte, int ackBit, MEMORY_TYPE memType, bool fixEndian) + { + int n = 1200; // 30 seconds + bool readValue = false; + bool writeValue = true; + bool ok = false; + // Set ack to 1 + CmsError libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue); + if (libraryError.IsError()) + return libraryError; + + do + { + // Check strobe + libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, strobeByte, strobeSubByte, strobeBit, ref readValue); + if (libraryError.IsError()) + return libraryError; + + // If true reset acknowledge + if (!readValue) + { + writeValue = false; + // Reset acknowledge + libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue); + if (libraryError.IsError()) + return libraryError; + // 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; + libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue); + if (libraryError.IsError()) + return libraryError; + } + + return libraryError; + } + + 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 libraryError = MEM_RWIntegerList(R, 0, + softKeyStatusMemory.MemType, + softKeyStatusMemory.Address, + softKeyStatusMemory.SubAddress, + memorySizeToRead / 4, + ref readValues); + + if (libraryError.IsError()) + return libraryError; + + // need byte swap! + List fixValues = new List(); + foreach (var item in readValues) + { + fixValues.Add(SwapBytes(item)); + } + // Convert ints into an array of bools + bool[] bits = IntToBits(fixValues.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; + } + + /// + /// Write ack for strobe received from PLC + /// + /// Apply endianness swap (word=yes, bitArray=no) + /// + /// + /// + /// + private CmsError PLC_WAck(bool fixEndian, MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id) + { + CmsError libraryError; + bool readValue = false; + bool writeValue = true; + + SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId); + + // Check Strobe + libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); + if (libraryError.IsError()) + return libraryError; + + // if there's a strobe --> give ack!!! + if (readValue) + { + // abbasso ack se fosse su... + libraryError = MEM_RWBoolean(W, fixEndian, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref writeValue); + if (libraryError.IsError()) + return libraryError; + + // attendo 50ms... + Thread.Sleep(50); + + // Reset wait ack = 1 and reset the strobe + libraryError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType, fixEndian); + if (libraryError.IsError()) + return libraryError; + + // exit and next round will continue... + return NO_ERROR; + } + + return NO_ERROR; + } + + /// + /// Write strobe and manage ack from PLC + /// + /// Apply endianness swap (word=yes, bitArray=no) + /// + /// + /// + /// + private CmsError PLC_WStrobe(bool fixEndian, MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id) + { + CmsError libraryError; + bool readValue = false; + bool writeValue = true; + + SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId); + + // Check Strobe + libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); + if (libraryError.IsError()) + return libraryError; + + // se è true + int n = 200; + do + { + // Check Strobe + libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); + Thread.Sleep(20); + n--; + } while (n > 0 && readValue); + + // If PLC is true --> reset + if (readValue) + { + bool forceVal = false; + libraryError = MEM_RWBoolean(W, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref forceVal); + } + + // Check ACK + libraryError = MEM_RWBoolean(R, fixEndian, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue); + if (libraryError.IsError()) + return libraryError; + + // If PLC it's performing another request then return + if (readValue) + return NO_ERROR; + + // Write strobe into memory + libraryError = MEM_RWBoolean(W, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref writeValue); + if (libraryError.IsError()) + return libraryError; + + // Reset wait ack = 1 and reset the strobe + libraryError = ResetStrobe(alarmBitId, strobeByte, ackByte, ackCell.MemType, fixEndian); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + 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 CmsError PROC_ReadActiveLine(uint processId, ref string line) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + //Read Static Data + private CmsError ReadStaticNCData() + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + +#if false + // prendo 2° valore(num max valori) + numByte = memByteRead[1]; + // poi prendo la stringa... + string outVal = ""; + for (int i = 2; i < numByte + 2; i++) + { + outVal += Char.ConvertFromUtf32(memByteRead[i]); + } +#endif + + // 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 + { + List currMem = new List(); + libraryError = MEM_RWByteList(R, 0, STATIC_DATA.MemType, STATIC_DATA.Address, STATIC_DATA.SubAddress, 0, STATIC_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + if (currMem.Count > 0) + { + // completare nuove variabili (matricola macchina, seriale PLC, firmware PLC) + S7Language = 0; + ConfChannelNo = 1; + Last_Static_Read = DateTime.Now; + Cnc_name = $"{currPLC.CPU}"; + // decodifico info! + byte[] memByteRead = currMem.Skip(0).Take(4).ToArray(); + int numByte = 0; + string outVal = ""; + for (int i = 0; i < 4; i++) + { + outVal += Char.ConvertFromUtf32(memByteRead[i]); + } + Cms_MachNumber = outVal; // matricola macchina, DB604.DBB6720..6723 + + memByteRead = currMem.Skip(4).Take(22).ToArray(); + outVal = ""; + numByte = memByteRead[1]; + for (int i = 2; i < numByte + 2; i++) + { + outVal += Char.ConvertFromUtf32(memByteRead[i]); + } + Cnc_SftVersion = outVal; // versione SW del firmware PLC/CNC | DB604.DBB6724..6745 + + memByteRead = currMem.Skip(26).Take(18).ToArray(); + outVal = ""; + numByte = memByteRead[1]; + for (int i = 2; i < numByte + 2; i++) + { + outVal += Char.ConvertFromUtf32(memByteRead[i]); + } + Cnc_SeriesNum = outVal; // seriale PLC/CNC | DB604.DBB6746..6763 + + memByteRead = currMem.Skip(44).Take(4).ToArray(); + outVal = ""; + outVal += Char.ConvertFromUtf32(memByteRead[0]); + for (int i = 1; i < 4; i++) + { + outVal += $"{memByteRead[i]}"; + } + PlcFirmware_SerialNum = outVal; // seriale PLC/CNC | DB604.DBB6764..6767 + + UnitOfMeasure = MILLIMETERS; + } + } + catch (Exception ex) + { + return ManageException(ex); + } + } + + return NO_ERROR; + } + + /// + /// Refresh Canali Riscaldi: actual current PLC + /// + private void refreshRiscActCurr() + { + // leggo DB514 x area Ich + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_ICH_DATA.MemType, RISC_ICH_DATA.Address, RISC_ICH_DATA.SubAddress, 0, RISC_ICH_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + double currVal = 0; + for (int i = 0; i < RISC_ICH_DATA.Size / 4; i++) + { + currVal = S7.Net.Types.Double.FromByteArray(memArray.Skip(4 * i).Take(4).ToArray()); + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + ThermoWarmChannels[i + 1].CurrAct = currVal; + } + else + { + try + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + CurrAct = currVal + }); + } + catch + { } + } + } + } + } + + /// + /// Refresh Canali Riscaldi: Percentuale lavoro Attuale + /// + private void refreshRiscPerc() + { + // leggo DB514 x area OVp + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_OVP_DATA.MemType, RISC_OVP_DATA.Address, RISC_OVP_DATA.SubAddress, 0, RISC_OVP_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < RISC_OVP_DATA.Size; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + ThermoWarmChannels[i + 1].PercAct = memArray[i]; + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + PercAct = memArray[i] + }); + } + } + } + } + + /// + /// Refresh Canali Riscaldi: SetPoint HMI + /// + private void refreshRiscSetpointHMI() + { + // leggo DB614 x area Ich + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < RISC_CHP_DATA.Size; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + try + { + ThermoWarmChannels[i + 1].SetpointHMI = memArray[i]; + } + catch + { } + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + SetpointHMI = memArray[i] + }); + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } + } + + /// + /// Refresh Canali Riscaldi: SetPoint PLC (% lavoro applicata ATTUALE dal PLC) + /// + private void refreshRiscSetpointPLC() + { + // leggo area DB627 (era DB514) x area CHp + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_PLC_DATA.MemType, RISC_PLC_DATA.Address, RISC_PLC_DATA.SubAddress, 0, RISC_PLC_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < RISC_PLC_DATA.Size; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + ThermoWarmChannels[i + 1].SetpointPLC = memArray[i]; + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + SetpointPLC = memArray[i] + }); + } + } + } + } + + /// + /// Refresh Canali Riscaldi: Status + /// + private void refreshRiscStatus() + { + // leggo DB514 x area ESP + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_ESP_DATA.MemType, RISC_ESP_DATA.Address, RISC_ESP_DATA.SubAddress, 0, RISC_ESP_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < RISC_ESP_DATA.Size; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + ThermoWarmChannels[i + 1].ChStatus = memArray[i]; + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + ChStatus = memArray[i] + }); + } + } + } + } + + /// + /// Refresh dati ThermoCamera dal PLC x area command/status + /// + private void refreshRiscTermoCamCommStatus() + { +#if false + // leggo DB614 x area Ich + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < RISC_CHP_DATA.Size; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + try + { + ThermoWarmChannels[i + 1].SetpointHMI = memArray[i]; + } + catch + { } + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + SetpointHMI = memArray[i] + }); + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } +#endif + } + + /// + /// Refresh dati ThermoCamera dal PLC x area command/status + /// + private void refreshRiscTermoCamEnab() + { + // leggo DB664 x abilitazione ch alla termocamera + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + bool[] bits = new bool[TCAM_CH_ENAB_DATA.Size * 8]; + + // Convert int into to true/false array + var bArray = new BitArray(currMem.ToArray()); + bArray.CopyTo(bits, 0); + + for (int i = 0; i < TCAM_CH_ENAB_DATA.Size * 8; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + try + { + ThermoWarmChannels[i + 1].TCamActive = bits[i]; + } + catch + { } + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + TCamActive = bits[i] + }); + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } + } + + /// + /// Refresh dati ThermoCamera dal PLC: ultima temp letta + /// + private void refreshRiscTermoCamTempAct() + { + // leggo DB625 x Temp attuale + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_ACT_DATA.MemType, TCAM_TEMP_ACT_DATA.Address, TCAM_TEMP_ACT_DATA.SubAddress, TCAM_TEMP_ACT_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + for (int i = 0; i < TCAM_TEMP_ACT_DATA.Size / 2; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + try + { + ThermoWarmChannels[i + 1].TCamTempActual = currMem[i]; + } + catch + { } + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + TCamTempActual = currMem[i] + }); + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } + } + + /// + /// Refresh dati ThermoCamera dal PLC: temperatura impostata come riferimento + /// + private void refreshRiscTermoCamTempSet() + { + // leggo DB624 x Setpoint Temp richiesti + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem); + + // copio! controllo SE ho dati... + if (currMem.Count > 0) + { + for (int i = 0; i < TCAM_TEMP_REQ_DATA.Size / 2; i++) + { + // cerco id + 1 (su memoria è base 0) + if (ThermoWarmChannels.ContainsKey(i + 1)) + { + try + { + ThermoWarmChannels[i + 1].TCamTempSet = currMem[i]; + } + catch + { } + } + else + { + ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() + { + IdChannel = i + 1, + TCamTempSet = currMem[i] + }); + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } + } + + private CmsError ResetAck(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType, bool fixEndian) + { + int n = 600; + bool readValue = false; + bool writeValue = false; + bool ok = false; + + // aspetto 100ms + Thread.Sleep(100); + + CmsError libraryError; + do + { + // Check Strobe + libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, TABLE, strobeByte, bitId, ref readValue); + if (libraryError.IsError()) + return libraryError; + + // If false reset ACK + if (readValue == false) + { + // Reset strobe + libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, ackByte, bitId, ref writeValue); + if (libraryError.IsError()) + return libraryError; + // Exit from cycle + n = 0; + ok = true; + } + else + { + // Decrement + n--; + // Wait befor next cycle + Thread.Sleep(20); + } + } while (n > 0); + + if (!ok) + { + // Reset ack (forced) + writeValue = false; + libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, ackByte, bitId, ref writeValue); + if (libraryError.IsError()) + return libraryError; + } + + return libraryError; + } + + private CmsError ResetStrobe(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType, bool fixEndian) + { + int n = 200; + bool readValue = false; + bool writeValue = false; + bool ok = false; + + CmsError libraryError; + do + { + // Check ACK + libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, TABLE, ackByte, bitId, ref readValue); + if (libraryError.IsError()) + return libraryError; + + // If true reset strobe + if (readValue == true) + { + // Reset strobe + libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, strobeByte, bitId, ref writeValue); + if (libraryError.IsError()) + return libraryError; + // Exit from cycle + n = 0; + ok = true; + } + else + { + // Decrement + n--; + // Wait befor next cycle + Thread.Sleep(20); + } + } while (n > 0); + + if (!ok) + { + writeValue = false; + // Reset strobe + libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, strobeByte, bitId, ref writeValue); + if (libraryError.IsError()) + return libraryError; + } + + return libraryError; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + private int SetBitValue(int intVal, bool val, int bitIndex) + { + if (val) + return intVal | (1 << (bitIndex - 1)); + else + return intVal & ~(1 << (bitIndex - 1)); + } + + /// + /// Setup memory for ack/strobe processing + /// + /// base addr for ack zone + /// base addr for strobe zone + /// parameters to set (id 1...n) + /// ack byte to use (OUT) + /// strobe byte to use (out) + /// bit 1..8 + 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 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); + } + + /// + /// 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; + } + + #endregion Private Methods + + #region Protected Methods + + /// + /// Refresh recipe parameters + /// + protected CmsError refreshChIOForced() + { + CmsError libraryError = NO_ERROR; + List readValuesDO = new List(); + List readValuesAO = new List(); + + // leggo da PLC a array di byte di appoggio x visibilità DO... + libraryError = MEM_RWWordList(R, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref readValuesDO); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC a array di byte di appoggio x visibilità AO... + libraryError = MEM_RWWordList(R, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref readValuesAO); + if (libraryError.IsError()) + return libraryError; + + ThermoIOFor.DO = convToDictIntBol(readValuesDO); + ThermoIOFor.AO = convToDictIntBol(readValuesAO); + + return libraryError; + } + + /// + /// Refresh recipe parameters + /// + protected CmsError refreshChIOForcedVal() + { + CmsError libraryError = NO_ERROR; + List readValuesDO = new List(); + List readValuesAO = new List(); + + // leggo da PLC valori DO... + libraryError = MEM_RWWordList(R, 0, IO_DO_VAL_FOR.MemType, IO_DO_VAL_FOR.Address, IO_DO_VAL_FOR.SubAddress, IO_DO_VAL_FOR.Size, ref readValuesDO); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC valori AO... + libraryError = MEM_RWShortList(R, 0, IO_AO_VAL_FOR.MemType, IO_AO_VAL_FOR.Address, IO_AO_VAL_FOR.SubAddress, IO_AO_VAL_FOR.Size, ref readValuesAO); + if (libraryError.IsError()) + return libraryError; + + ThermoIOValFor.DO = convToDictIntBol(readValuesDO); + ThermoIOValFor.AO = convToDictIntInt(readValuesAO); + + return libraryError; + } + + /// + /// Refresh IO channels actual value + /// + /// + protected CmsError refreshChIOVal() + { + CmsError libraryError = NO_ERROR; + 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_VAL_ACT.MemType, IO_DI_VAL_ACT.Address, IO_DI_VAL_ACT.SubAddress, IO_DI_VAL_ACT.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_VAL_ACT.MemType, IO_DO_VAL_ACT.Address, IO_DO_VAL_ACT.SubAddress, IO_DO_VAL_ACT.Size, ref readValuesDO); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC a array di byte di appoggio x visibilità AI... + libraryError = MEM_RWShortList(R, 0, IO_AI_VAL_ACT.MemType, IO_AI_VAL_ACT.Address, IO_AI_VAL_ACT.SubAddress, IO_AI_VAL_ACT.Size, ref readValuesAI); + if (libraryError.IsError()) + return libraryError; + // leggo da PLC a array di byte di appoggio x visibilità AO... + libraryError = MEM_RWShortList(R, 0, IO_AO_VAL_ACT.MemType, IO_AO_VAL_ACT.Address, IO_AO_VAL_ACT.SubAddress, IO_AO_VAL_ACT.Size, ref readValuesAO); + if (libraryError.IsError()) + return libraryError; + + ThermoIOVal.DI = convToDictIntBol(readValuesDI); + ThermoIOVal.DO = convToDictIntBol(readValuesDO); + ThermoIOVal.AI = convToDictIntInt(readValuesAI); + ThermoIOVal.AO = convToDictIntInt(readValuesAO); + + return libraryError; + } + + /// + /// Refresh recipe parameters + /// + protected CmsError refreshChIOVisib() + { + CmsError libraryError = NO_ERROR; + 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 = convToDictIntBol(readValuesDI); + ThermoIOVis.DO = convToDictIntBol(readValuesDO); + ThermoIOVis.AI = convToDictIntBol(readValuesAI); + ThermoIOVis.AO = convToDictIntBol(readValuesAO); + + return libraryError; + } + + /// + /// Refresh ModuleBlock + /// + protected void refreshMemModBlockParameter() + { + List currMem = new List(); + int packSize = 18; + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, MODULE_DATA.MemType, MODULE_DATA.Address, MODULE_DATA.SubAddress, 0, MODULE_DATA.Size, ref currMem); + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < MODULE_DATA.Size / packSize; i++) + { + PlcModBlock currModBlock = new PlcModBlock(memArray.Skip(i * packSize).Take(packSize).ToArray()); + // calcolo lista PrecId + List PrecId = new List(); + PrecId.Add(currModBlock.PrevId_01); + PrecId.Add(currModBlock.PrevId_02); + PrecId.Add(currModBlock.PrevId_03); + // solo se ID > 0... + if (currModBlock.Id > 0) + { + // update oggetto thermoParamList... + if (ThermoModuleList.ContainsKey(currModBlock.Id)) + { + ThermoModuleList[currModBlock.Id].EstimatedDelay = currModBlock.EstimDelay; + ThermoModuleList[currModBlock.Id].EstimatedDuration = currModBlock.EstimDuration; + ThermoModuleList[currModBlock.Id].PrecedingId = PrecId; + } + else + { + ThermoModuleList.Add(currModBlock.Id, new ThermoModels.ModuleBlock() + { + Id = currModBlock.Id, + EstimatedDelay = currModBlock.EstimDelay, + EstimatedDuration = currModBlock.EstimDuration, + PrecedingId = PrecId + }); + } + } + else + { + libraryError = S7_PLC_WRONG_DATA; + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } + } + + /// + /// Refresh ModuleBlock RT + /// + protected void refreshMemModBlockParameterRT() + { + List currMem = new List(); + int packSize = 12; + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWByteList(R, 0, MODULE_RT_DATA.MemType, MODULE_RT_DATA.Address, MODULE_RT_DATA.SubAddress, 0, MODULE_RT_DATA.Size, ref currMem); + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di 8 byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < MODULE_RT_DATA.Size / packSize; i++) + { + PlcModBlockRT currModBlock = new PlcModBlockRT(memArray.Skip(i * packSize).Take(packSize).ToArray()); + // solo se ID > 0... + if (currModBlock.Id > 0) + { + // update oggetto thermoParamList... + if (ThermoModuleList.ContainsKey(currModBlock.Id)) + { + try + { + ThermoModuleList[currModBlock.Id].Visible = currModBlock.Visible; + ThermoModuleList[currModBlock.Id].Running = currModBlock.Running; + ThermoModuleList[currModBlock.Id].HasError = currModBlock.HasError; + ThermoModuleList[currModBlock.Id].Terminated = currModBlock.Terminated; + ThermoModuleList[currModBlock.Id].ActualDuration = currModBlock.ActualDuration; + ThermoModuleList[currModBlock.Id].ActualDelay = currModBlock.ActualDelay; + } + catch + { } + } + else + { + try + { + ThermoModuleList.Add(currModBlock.Id, new ThermoModels.ModuleBlock() + { + Id = currModBlock.Id, + ActualDuration = currModBlock.ActualDuration, + ActualDelay = currModBlock.ActualDelay, + Visible = currModBlock.Visible, + Running = currModBlock.Running, + HasError = currModBlock.HasError, + Terminated = currModBlock.Terminated + }); + } + catch + { } + } + } + else + { + libraryError = S7_PLC_WRONG_DATA; + } + } + } + else + { + libraryError = S7_PLC_EMPTY_READ; + } + } + + /// + /// Refresh recipe parameters + /// + protected CmsError refreshMemRecipeParameter() + { + CmsError libraryError = NO_ERROR; + 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; + } + + return libraryError; + } + + /// + /// Refresh recipE parameters RT + /// + protected CmsError refreshMemRecipeParameterRT() + { + CmsError libraryError = NO_ERROR; + 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 + { } + } + } + } + } + + return libraryError; + } + + #endregion Protected Methods + + #region Public Methods + + public static byte[] boolsToByteArray(bool[] bits) + { + // pack (in this case, using the first bool as the lsb - if you want + // the first bool as the msb, reverse things ;-p) + int bytes = bits.Length / 8; + if ((bits.Length % 8) != 0) bytes++; + byte[] answ = new byte[bytes]; + int bitIndex = 0, byteIndex = 0; + for (int i = 0; i < bits.Length; i++) + { + if (bits[i]) + { + answ[byteIndex] |= (byte)(((byte)1) << bitIndex); + } + bitIndex++; + if (bitIndex == 8) + { + bitIndex = 0; + byteIndex++; + } + } + + return answ; + } + + public override CmsError AXES_RAxesNames(ushort channel, ref List axesData) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_RDistanceToGo(ushort channel, ref Dictionary axes) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_RFollowingError(ushort channel, ref Dictionary axes) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_RInterpPosition(ushort channel, ref Dictionary axes) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_RMachinePosition(ushort channel, ref Dictionary axes) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_ROrigin(int numberOfAxes) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_RProgrPosition(ushort channel, ref Dictionary axes) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_RSelectedAxis(ref byte axisId) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError AXES_WSelectAxis(byte axisId) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_CopyProgram(string partProgramPath, string newPartProgramPath, bool failIfExist) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_DeleteProgram(string partProgramPath, string partProgramName) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + /// + /// Load selected recipe, convert and save to PLC memory area + /// + /// + /// + /// + public CmsError FILES_LoadRecipe(string path, string name) + { + return NO_ERROR; + } + + public override CmsError FILES_RActiveProgramData(int processId, ref ActiveProgramDataModel programData) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + /// + /// Get list of recipe (from local PC area) + /// + /// + /// + /// + public CmsError FILES_RecipeList(string path, ref List file) + { + return NO_ERROR; + } + + public override CmsError FILES_RGetFileInfo(string path, ref InfoFile fileInfo) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_RGetFileList(string path, ref List files) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_RGetProgramType(ref PROGRAM_TYPE_ENUM programType) + { + programType = PROGRAM_TYPE_ENUM.PART_PROGRAM; + + return NO_ERROR; + } + + public override CmsError FILES_RProgramToFile(string partProgramPath, FileStream localFile) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_RQueueData(ref List statusList) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_RQueueDataByProcess(ref QueueStatusModel status, int processId) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// Save current recipe from PLC memory area to file + /// + /// + /// + /// + public CmsError FILES_SaveRecipe(string path, string name) + { + return NO_ERROR; + } + + public override CmsError FILES_UploadPartProgram(string localPath, string name, ref string newFilePath) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WCleanUploadFolder() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WDeactivateProgram(int processId) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WLoadNextPartProgram(string localPath, string ncFileName) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WProgramFromFile(string partProgramPath, FileStream localFile) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WSetActiveProgram(int processId, string filePath, ref ActiveProgramDataModel data) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WStartQueue() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WStopQueue() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WUploadCustomMainProgramAndActivate(int processId, string customPartProgramContent, ref ActiveProgramDataModel activeData) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError FILES_WUploadJobFilesAndActivate(int processId, string jobExtractedPath, string fileToActivate) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + //Read-Write a Boolean-Value inside the NC. + public override CmsError MEM_RWBoolean(bool bWrite, bool fixEndian, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemBit, ref bool Value) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + //Check if the Bit Number is Correct + libraryError = CheckBitRange(MemBit); + if (libraryError.IsError()) + return libraryError; + + byte bValue = 0; + ushort pow = (ushort)Math.Pow(2, MemBit); + + //Read the Byte where is the bit + libraryError = MEM_RWByte(R, fixEndian, Process, MemType, MemTable, MemIndex, 0, ref bValue); + if (libraryError.IsError()) + return libraryError; + + //If i have to Write -> Write the Bit + if (bWrite) + { + if (Value) + bValue = (byte)(bValue | (1 << MemBit)); + else + bValue = (byte)(bValue & ~(1 << MemBit)); + + libraryError = MEM_RWByte(W, fixEndian, Process, MemType, MemTable, MemIndex, 0, ref bValue); + if (libraryError.IsError()) + return libraryError; + } + //If i have to read -> Read the Bit + else + { + Value = (bValue & pow) == pow; + } + + return NO_ERROR; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// Read-Write a SINGLE Byte inside the NC. In writing-mode the field "Number" is not required + /// + /// R/W mode + /// fix endianness + /// + /// + /// + /// + /// + /// + /// + public override CmsError MEM_RWByte(bool bWrite, bool fixEndian, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByte, ref byte Value) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + // attenzione endianness! inverte byte se richiesto... + int fixIndex = MemIndex; + if (fixEndian) + { + fixIndex = MemIndex % 2 == 0 ? MemIndex + 1 : MemIndex - 1; + } + + // vere operazioni R/W + if (bWrite) + { + // try/catch + try + { + byte[] DB_Byte = new byte[1]; + DB_Byte[0] = Value; + currPLC.WriteBytes(DataType.DataBlock, MemTable, fixIndex, DB_Byte); + } + catch + { + return S7_PLC_WRITE_ERROR_BYTE; + } + } + else + { + try + { + var memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, fixIndex, 1); + Value = memByteRead[0]; + } + catch + { + return S7_PLC_READ_ERROR_BYTE; + } + } + + return NO_ERROR; + } + + public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByteStart, int Number, ref List Values) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + if (bWrite) + { + //Prevent some exceptions + if (Values.Count == 0) + return NO_ERROR; + // try/catch + try + { + currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, Values.ToArray()); + } + catch + { + return S7_PLC_WRITE_ERROR_LST_BYTE; + } + } + else + { + // Prevent some exceptions + if (Number == 0) + return NO_ERROR; + Values.Clear(); + try + { + byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); + Values = memByteRead.ToList(); + } + catch + { + return S7_PLC_READ_ERROR_LST_BYTE; + } + } + + return NO_ERROR; + } + + public override CmsError MEM_RWDouble(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref double Value) + { + List ListValue = new List() { Value }; + + //uses the List method with one-element list + CmsError libraryError = MEM_RWDoubleList(bWrite, Process, MemType, MemTable, MemIndex, 4, ref ListValue); + if (libraryError.IsError()) + return libraryError; + + Value = ListValue.First(); + + return NO_ERROR; + } + + public override CmsError MEM_RWDoubleList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + if (bWrite) + { + //Prevent some exceptions + if (Values.Count == 0) + return NO_ERROR; + + byte[] singleItem = new byte[4]; + List memByteList = new List(); + + foreach (var Item in Values) + { + singleItem = S7.Net.Types.Double.ToByteArray(Item); + memByteList.AddRange(singleItem); + } + + try + { + currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); + } + catch + { + return S7_PLC_WRITE_ERROR_LST_DOUBLE; + } + } + else + { + // Prevent some exceptions + if (Number == 0) + return NO_ERROR; + + Values.Clear(); + + try + { + byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); + // converto a word! + double shortVal = 0; + for (int i = 0; i < memByteRead.Length / 4; i++) + { + shortVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); + Values.Add(shortVal); + } + } + catch + { + return S7_PLC_READ_ERROR_LST_DOUBLE; + } + } + + 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 libraryError = MEM_RWDWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue); + if (libraryError.IsError()) + return libraryError; + + Value = ListValue.First(); + + return NO_ERROR; + } + + public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + if (bWrite) + { + //Prevent some exceptions + if (Values.Count == 0) + return NO_ERROR; + + byte[] singleItem = new byte[4]; + List memByteList = new List(); + + foreach (var Item in Values) + { + singleItem = S7.Net.Types.DWord.ToByteArray(Item); + memByteList.AddRange(singleItem); + } + + try + { + currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); + } + catch + { + return S7_PLC_WRITE_ERROR_LST_DWORD; + } + } + else + { + // Prevent some exceptions + if (Number == 0) + return NO_ERROR; + + Values.Clear(); + + try + { + byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); + // converto a word! + uint shortVal = 0; + for (int i = 0; i < memByteRead.Length / 4; i++) + { + shortVal = S7.Net.Types.DWord.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); + Values.Add(shortVal); + } + } + catch + { + return S7_PLC_READ_ERROR_LST_DWORD; + } + } + + 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, reading int32 (4byte) data... + CmsError libraryError = MEM_RWIntegerList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue); + if (libraryError.IsError()) + return libraryError; + if (ListValue.Count > 0) + { + Value = ListValue.First(); + } + + return NO_ERROR; + } + + /// + /// Lettura lista di interi + /// + /// + /// + /// + /// + /// + /// numero di INT 32 da leggere (byte/4) + /// + /// + public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + if (bWrite) + { + //Prevent some exceptions + if (Values.Count == 0) + return NO_ERROR; + + byte[] singleItem = new byte[4]; + List memByteList = new List(); + + foreach (var Item in Values) + { + singleItem = S7.Net.Types.DInt.ToByteArray(Item); + memByteList.AddRange(singleItem); + } + try + { + currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); + } + catch + { + return S7_PLC_WRITE_ERROR_LST_INT; + } + } + else + { + // Prevent some exceptions + if (Number == 0) + return NO_ERROR; + + Values.Clear(); + byte[] memByteRead = null; + try + { + memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number * 4); + // converto a word! + int intVal = 0; + for (int i = 0; i < memByteRead.Length / 4; i++) + { + intVal = S7.Net.Types.DInt.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); + Values.Add(intVal); + } + } + catch + { + return S7_PLC_READ_ERROR_LST_INT; + } + } + + if (Values.Count == 0) + { + return NOT_CONNECTED_ERROR; + } + + 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 libraryError = MEM_RWShortList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue); + if (libraryError.IsError()) + return libraryError; + + Value = ListValue.First(); + + return NO_ERROR; + } + + public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) + { + //Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + if (bWrite) + { + //Prevent some exceptions + if (Values.Count == 0) + return NO_ERROR; + + byte[] singleItem = new byte[2]; + List memByteList = new List(); + + foreach (var Item in Values) + { + singleItem = S7.Net.Types.Int.ToByteArray(Item); + memByteList.AddRange(singleItem); + } + try + { + currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); + } + catch + { + return S7_PLC_WRITE_ERROR_LST_SHORT; + } + } + else + { + // Prevent some exceptions + if (Number == 0) + return NO_ERROR; + + Values.Clear(); + try + { + byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); + // converto a word! + short shortVal = 0; + for (int i = 0; i < memByteRead.Length / 2; i++) + { + shortVal = S7.Net.Types.Int.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray()); + Values.Add(shortVal); + } + } + catch + { + return S7_PLC_READ_ERROR_LST_SHORT; + } + } + + 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 libraryError = MEM_RWWordList(bWrite, Process, MemType, MemTable, MemIndex, 2, ref ListValue); + if (libraryError.IsError()) + return libraryError; + if (ListValue.Count > 0) + Value = ListValue.First(); + + return NO_ERROR; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) + { + ////Check if the NC is Connected + CmsError libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + if (MemType != MEMORY_TYPE.Siemens_DB) + { + return INCORRECT_PARAMETERS_ERROR; + } + + libraryError = null; + + if (bWrite) + { + //Prevent some exceptions + if (Values.Count == 0) + return NO_ERROR; + + byte[] singleItem = new byte[2]; + List memByteList = new List(); + + foreach (var Item in Values) + { + singleItem = S7.Net.Types.Word.ToByteArray(Item); + memByteList.AddRange(singleItem); + } + try + { + currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); + } + catch + { + return S7_PLC_WRITE_ERROR_LST_WORD; + } + } + else + { + // Prevent some exceptions + if (Number == 0) + return NO_ERROR; + + Values.Clear(); + byte[] memByteRead; + try + { + memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); + // converto a word! + ushort shortVal = 0; + for (int i = 0; i < memByteRead.Length / 2; i++) + { + shortVal = S7.Net.Types.Word.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray()); + Values.Add(shortVal); + } + } + catch + { + return S7_PLC_READ_ERROR_LST_WORD; + } + } + + return NO_ERROR; + } + /// /// Connessione al PLC /// @@ -174,10 +2654,9 @@ namespace CMS_CORE_Library.S7Net SiemensAlarms = new Alarm[] { }; SiemensAlmSvc = new AlarmSvc(ConvertToSTEPLanguage(SiemensLanguage).ThreeLetterISOLanguageName); SiemensAlmSvc.Subscribe(AlarmsChanged); - Infrastructure.SubscribeLanguageChanged(NcLanguageChanged); + Infrastructure.SubscribeLanguageChanged(NcLanguageChanged); #endif } - } catch (Exception ex) { @@ -186,6 +2665,7 @@ namespace CMS_CORE_Library.S7Net } return NO_ERROR; } + /// /// Disconnect Method /// @@ -205,6 +2685,55 @@ namespace CMS_CORE_Library.S7Net } return NO_ERROR; } + + /// + /// Elenco lingue disponibili + /// + /// + /// + public override CmsError NC_GetAvailableLanguages(ref ICollection languages) + { + // FIXME TODO +#if false + 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); + } +#endif + + var lang = GetCultureFromThreeLetter("eng"); + if (lang != null) + languages.Add(lang); + lang = GetCultureFromThreeLetter("ita"); + if (lang != null) + languages.Add(lang); + + return NO_ERROR; + } + /// /// Compilazione dizionario allarmi x lingua /// @@ -232,7 +2761,6 @@ namespace CMS_CORE_Library.S7Net .Select(line => line.Split(',')) .Where(line => line.Count() == 2) .ToDictionary(line => Convert.ToInt32(line[0]), line => line[1].Trim()); - } catch (Exception ex) { @@ -240,6 +2768,7 @@ namespace CMS_CORE_Library.S7Net } return NO_ERROR; } + /// /// Compilazione dizionario traduzioni THermo /// @@ -280,7 +2809,6 @@ namespace CMS_CORE_Library.S7Net // combine 2 dictionary... messages = dict01.Union(dict02).ToDictionary(d => d.Key, d => d.Value); - } catch (Exception ex) { @@ -288,180 +2816,16 @@ namespace CMS_CORE_Library.S7Net } return NO_ERROR; } - /// - /// Elenco lingue disponibili - /// - /// - /// - public override CmsError NC_GetAvailableLanguages(ref ICollection languages) - { - // FIXME TODO -#if false - 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); - } -#endif - - var lang = GetCultureFromThreeLetter("eng"); - if (lang != null) - languages.Add(lang); - lang = GetCultureFromThreeLetter("ita"); - if (lang != null) - languages.Add(lang); - - return NO_ERROR; - } - - #endregion Contructor & global methods /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #region High level methods - /// - /// Get the processes-count configurated + /// Get the Nc Active Alarms /// - /// + /// /// - public override CmsError NC_RProcessesNum(ref ushort ProcNumber) + public override CmsError NC_RActiveAlarms(ref List alarms) { - CmsError libraryError = ReadStaticNCData(); - if (libraryError.IsError()) - return libraryError; - - ProcNumber = (ushort)ConfChannelNo; - - return NO_ERROR; - } - - /// - /// Get the NC model Name - /// - /// - /// - public override CmsError NC_RModelName(ref string ModelName) - { - CmsError libraryError = ReadStaticNCData(); - if (libraryError.IsError()) - return libraryError; - - ModelName = Cnc_name; - - return NO_ERROR; - } - - /// - /// Get the NC Software Version - /// - /// - /// - public override CmsError NC_RSoftwareVersion(ref string SWV) - { - CmsError libraryError = ReadStaticNCData(); - if (libraryError.IsError()) - return libraryError; - - SWV = Cnc_SftVersion; - - return NO_ERROR; - } - - /// - /// Get the NC Language - /// - /// - /// - public override CmsError NC_RLanguage(ref CultureInfo Language) - { - // Read static data - CmsError libraryError = ReadStaticNCData(); - if (libraryError.IsError()) - return libraryError; - - Language = ConvertToSTEPLanguage(S7Language); - - return NO_ERROR; - } - - /// - /// Set the NC Language - /// - /// - /// - public override CmsError NC_WLanguage(CultureInfo Language) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - /// - /// Get the NC Serial number - /// - /// - /// - public override CmsError NC_RSerialNumber(ref string serialNumber) - { - CmsError libraryError = ReadStaticNCData(); - if (libraryError.IsError()) - return libraryError; - - serialNumber = Cnc_SeriesNum; - - return NO_ERROR; - } - - /// - /// Get CMS Machine number - /// - /// - /// - /// - public override CmsError NC_RMachineNumber(bool hasLetters, ref string MachNumber) - { - if (!hasLetters) - { - CmsError libraryError = ReadStaticNCData(); - if (libraryError.IsError()) - return libraryError; - - MachNumber = Cms_MachNumber; - } - else - { - // New method to read machine number - List lists = new List(); - CmsError libraryError = MEM_RWByteList(R, 0, NEW_MATR_MACC.MemType, NEW_MATR_MACC.Address, NEW_MATR_MACC.SubAddress, 0, 4, ref lists); - if (libraryError.IsError()) - return libraryError; - - lists.Reverse(); - - MachNumber = Encoding.ASCII.GetString(lists.ToArray().Reverse().ToArray()); - } - return NO_ERROR; } @@ -508,6 +2872,145 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } + /// + /// Get the NC Language + /// + /// + /// + public override CmsError NC_RLanguage(ref CultureInfo Language) + { + // Read static data + CmsError libraryError = ReadStaticNCData(); + if (libraryError.IsError()) + return libraryError; + + Language = ConvertToSTEPLanguage(S7Language); + + return NO_ERROR; + } + + /// + /// Get CMS Machine number + /// + /// + /// + /// + public override CmsError NC_RMachineNumber(bool hasLetters, ref string MachNumber) + { + if (!hasLetters) + { + CmsError libraryError = ReadStaticNCData(); + if (libraryError.IsError()) + return libraryError; + + MachNumber = Cms_MachNumber; + } + else + { + // New method to read machine number + List lists = new List(); + CmsError libraryError = MEM_RWByteList(R, 0, NEW_MATR_MACC.MemType, NEW_MATR_MACC.Address, NEW_MATR_MACC.SubAddress, 0, 4, ref lists); + if (libraryError.IsError()) + return libraryError; + + lists.Reverse(); + + MachNumber = Encoding.ASCII.GetString(lists.ToArray().Reverse().ToArray()); + } + + return NO_ERROR; + } + + /// + /// Get the NC model Name + /// + /// + /// + public override CmsError NC_RModelName(ref string ModelName) + { + CmsError libraryError = ReadStaticNCData(); + if (libraryError.IsError()) + return libraryError; + + ModelName = Cnc_name; + + return NO_ERROR; + } + + 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; + } + + /// + /// Get the processes-count configurated + /// + /// + /// + public override CmsError NC_RProcessesNum(ref ushort ProcNumber) + { + CmsError libraryError = ReadStaticNCData(); + if (libraryError.IsError()) + return libraryError; + + ProcNumber = (ushort)ConfChannelNo; + + return NO_ERROR; + } + + /// + /// Get the NC Serial number + /// + /// + /// + public override CmsError NC_RSerialNumber(ref string serialNumber) + { + CmsError libraryError = ReadStaticNCData(); + if (libraryError.IsError()) + return libraryError; + + serialNumber = Cnc_SeriesNum; + + return NO_ERROR; + } + + /// + /// Get the NC Software Version + /// + /// + /// + public override CmsError NC_RSoftwareVersion(ref string SWV) + { + CmsError libraryError = ReadStaticNCData(); + if (libraryError.IsError()) + return libraryError; + + SWV = Cnc_SftVersion; + + return NO_ERROR; + } + /// /// Get NC unit of measure /// @@ -524,16 +3027,6 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } - /// - /// Get the Nc Active Alarms - /// - /// - /// - public override CmsError NC_RActiveAlarms(ref List alarms) - { - return NO_ERROR; - } - /// /// Set the Nc Active Page of the NC /// @@ -544,30 +3037,44 @@ namespace CMS_CORE_Library.S7Net return FUNCTION_NOT_ALLOWED_ERROR; } + /// + /// Set the NC Language + /// + /// + /// + public override CmsError NC_WLanguage(CultureInfo Language) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + public override CmsError NC_WMDICommand(int processId, string mdiString) { return FUNCTION_NOT_ALLOWED_ERROR; } - #endregion High level methods - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - #region PLC High-level data - - public override CmsError PLC_RWManageWatchdog() + public override CmsError PLC_RActiveClient(ref int clientId) { - // watchdog in memoria WORD --> true x endianness! - bool plcWatchdog = false; - CmsError libraryError = MEM_RWBoolean(R, true, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog); + CmsError libraryError = CheckConnection(); if (libraryError.IsError()) return libraryError; - if (plcWatchdog) - return PLC_NOT_RUNNING_ERROR; - // tira su il bit... - plcWatchdog = true; - return MEM_RWBoolean(W, true, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog); + byte readValues = 0; + libraryError = MEM_RWByte(R, true, 0, ACTIVE_CLIENT.MemType, ACTIVE_CLIENT.Address, ACTIVE_CLIENT.SubAddress, 0, ref readValues); + if (libraryError.IsError()) + return libraryError; + + // 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; } /// @@ -652,38 +3159,480 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } - public override CmsError PLC_WRestoreMessage(uint id) + public override CmsError PLC_RAssistedToolingData(ref AssistedToolingModel data) { - // Check id range - if (id > ALARMS_NUMBER) - return INCORRECT_PARAMETERS_ERROR; + return FUNCTION_NOT_ALLOWED_ERROR; + } - // Call restore message: is a BIT ARRAY --> true! - CmsError libraryError = PLC_WStrobe(true, ALARM_ACK, ALARM_RESTORATION_STROBE, id); + /// + /// Get current Production Info data + /// + /// + /// + public override CmsError PLC_RAxesMov(ref ThermoModels.AxisRT currProdInfo) + { + List currMem = new List(); + CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem); if (libraryError.IsError()) return libraryError; +#if false + // converto! + currProdInfo = new ThermoModels.ProdInfoModel() + { + NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()), + NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()), + // cicli preriscaldo? FIXME TODO + TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()), + TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()), + TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()), + TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()), + TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()), + MaterialTempEndWarm = S7.Net.Types.Double.FromByteArray(currMem.Skip(26).Take(4).ToArray()), + MaterialTempEndVent = S7.Net.Types.Double.FromByteArray(currMem.Skip(30).Take(4).ToArray()), + MoldTemp = S7.Net.Types.Double.FromByteArray(currMem.Skip(34).Take(4).ToArray()), + VacuumReadVal = S7.Net.Types.Double.FromByteArray(currMem.Skip(38).Take(4).ToArray()), + MouldEnergyOUT = S7.Net.Types.Double.FromByteArray(currMem.Skip(42).Take(4).ToArray()), + MouldEnergyIN = S7.Net.Types.Double.FromByteArray(currMem.Skip(46).Take(4).ToArray()) + }; +#endif + return NO_ERROR; } - public override CmsError PLC_WRefreshMessage(uint id) + public override CmsError PLC_RAxesResetData(ref AxisResetDataModel axisResetData) { - // Check id range - if (id > ALARMS_NUMBER) - return INCORRECT_PARAMETERS_ERROR; - - // Call restore message: is a BIT ARRAY --> false! - CmsError libraryError = PLC_WStrobe(false, ALARM_ACK, ALARM_REFRESH_STROBE, id); + byte value = 0; + // Read byte from memory + CmsError libraryError = MEM_RWByte(R, true, 0, AXIS_RESET_PROCEDURE.MemType, AXIS_RESET_PROCEDURE.Address, AXIS_RESET_PROCEDURE.SubAddress, 0, ref value); if (libraryError.IsError()) return libraryError; + // 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_WRefreshAllMessages() + /// + /// Get current Axis Info data + /// + /// + /// + public override CmsError PLC_RAxisInfoList(ref Dictionary currAxisInfo) { - // imposto come UserSoftKey - return PLC_WUserSoftKey(REFRESH_ALL_ALARMS_SFKEY_INDEX); + CmsError libraryError = NO_ERROR; +#if false + CmsError libraryError = NO_ERROR; + 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; + } + + + /// + /// Get current LOG Cycle data + /// + /// + /// + public override CmsError PLC_RLogCycleData(out List currLogCycle) + { + CmsError libraryError = NO_ERROR; + List currMem = new List(); + int packSize = 10; + currLogCycle = new List(); + + // leggo da PLC a array di byte di appoggio... + libraryError = MEM_RWByteList(R, 0, LOG_CYCLE_DATA.MemType, LOG_CYCLE_DATA.Address, LOG_CYCLE_DATA.SubAddress, 0, LOG_CYCLE_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < LOG_CYCLE_DATA.Size / packSize; i++) + { + ThermoModels.LogCycleData currData = new ThermoModels.LogCycleData(memArray.Skip(i * packSize).Take(packSize).ToArray()); + // se il valore ricevuto di evento è > 0... + if (currData.Code > 0) + { + try + { + currLogCycle.Add(currData); + } + catch + { } + } + } + } + return libraryError; + } + + /// + /// Get current Axis RT data + /// + /// + /// + public override CmsError PLC_RAxisRTList(ref Dictionary currAxisRT) + { + CmsError libraryError = NO_ERROR; + List currMem = new List(); + int packSize = 12; + + // leggo da PLC a array di byte di appoggio... + libraryError = MEM_RWByteList(R, 0, AXES_RTDATA.MemType, AXES_RTDATA.Address, AXES_RTDATA.SubAddress, 0, AXES_RTDATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + // controllo SE ho dati... + if (currMem.Count > 0) + { + // converto a blocchi di byte... + byte[] memArray = currMem.ToArray(); + for (int i = 0; i < AXES_RTDATA.Size / packSize; i++) + { + ThermoModels.AxisRT currData = new ThermoModels.AxisRT(i + 1, memArray.Skip(i * packSize).Take(packSize).ToArray()); + // solo se ID > 0... + if (currData.Id > 0) + { + // update oggetto thermoParamList... + if (currAxisRT.ContainsKey(currData.Id)) + { + try + { + currAxisRT[currData.Id].Position = currData.Position; + currAxisRT[currData.Id].Speed = currData.Speed; + currAxisRT[currData.Id].Load = currData.Load; + } + catch + { } + } + else + { + try + { + currAxisRT.Add(currData.Id, currData); + } + catch + { } + } + } + } + } + return libraryError; + } + + public override CmsError PLC_RCandy(ref long value) + { + // Long is formed by a integer + word + // Read word + ushort word = 0; + CmsError libraryError = MEM_RWWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word); + if (libraryError.IsError()) + return libraryError; + + // Read first int + uint firtInt = 0; + libraryError = MEM_RWDWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref firtInt); + if (libraryError.IsError()) + return libraryError; + + // Build Long value + value = ((long)firtInt << 16) + word; + + return NO_ERROR; + } + + public override CmsError PLC_RExpiredCandy(ref bool value) + { + CmsError libraryError = MEM_RWBoolean(R, true, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value); + if (libraryError.IsError()) + return libraryError; + 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 libraryError = MEM_RWIntegerList(R, 0, FUNCTION_ACCESS.MemType, FUNCTION_ACCESS.Address, FUNCTION_ACCESS.SubAddress, numberOfIntegers, ref readValues); + if (libraryError.IsError()) + return libraryError; + + 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, + // forzo a true perché non gestita dal PLC + IsActive = true //bits[i] + }); + } + + return NO_ERROR; + } + + /// + /// Get gauge data + /// + /// + /// + public override CmsError PLC_RGaugeData(ref ThermoModels.LiveProdDataModel gaugeData) + { + List Values = new List(); + CmsError libraryError = MEM_RWIntegerList(R, 1, MACHINE_GAUGE_DATA.MemType, MACHINE_GAUGE_DATA.Address, MACHINE_GAUGE_DATA.SubAddress, MACHINE_GAUGE_DATA.Size / 4, ref Values); + + if (libraryError.IsError()) + return libraryError; + + gaugeData = new ThermoModels.LiveProdDataModel() + { + TimeAdv = Convert.ToUInt32(Values[0]), + Power = Values[1], + Vacuum = Values[2], + Air = Values[3], + }; + + return NO_ERROR; + } + + public override CmsError PLC_RHeadsData(List heads, int number) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + /// + /// Read PLC current IO Channels visibility (conf) + /// + /// Visibility status for all channels + /// + public override CmsError PLC_RIOChannelsConf(ref ThermoModels.ChanIOVis currThermoIOVis) + { + CmsError currError = NO_ERROR; + // refresh dati + refreshChIOVisib(); + + // copio liste in output... + currThermoIOVis = ThermoIOVis; + + // esco + return currError; + } + + /// + /// Read PLC current IO Channels VALUES (actual + forced) + /// + /// Values for channels + /// Indicates if values are forced by UI + /// Values forced by UI + /// + public override CmsError PLC_RIOChannelsVal(ref ThermoModels.ChanIOVal currThermoIOVal, ref ThermoModels.ChanIOFor currThermoIOFor, ref ThermoModels.ChanIOValFor currThermoIOValFor) + { + CmsError currError = NO_ERROR; + // refresh dati veloci (valori) + refreshChIOVal(); + refreshChIOForced(); + refreshChIOForcedVal(); + + // copio liste in output... + currThermoIOVal = ThermoIOVal; + currThermoIOFor = ThermoIOFor; + currThermoIOValFor = ThermoIOValFor; + + // esco + return currError; + } + + public override CmsError PLC_RM154Data(ref List data, ref bool MTCOnOff) + { + // FIXME TODO - levare? inserito anche endiannes + + MTCOnOff = false; + CmsError libraryError = MEM_RWBoolean(R, true, 0, M154_SWITCH_ONOFF.MemType, M154_SWITCH_ONOFF.Address, M154_SWITCH_ONOFF.SubAddress, 1, ref MTCOnOff); + + if (libraryError.IsError()) + return libraryError; + + byte val = 0; + libraryError = MEM_RWByte(R, true, 0, M154_STROBE.MemType, M154_STROBE.Address, M154_STROBE.SubAddress, 0, ref val); + if (libraryError.IsError()) + return libraryError; + + // 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 + libraryError = PROC_ReadActiveLine(processId, ref tmpStr); + if (libraryError.IsError()) + return libraryError; + + // Parse parameters + parameters = ExtractM154ParametersFromNcCodeLine(tmpStr); + data.Add(new M154DataModel() + { + Process = processId, + IsNeeded = bits[processId - 1], + Parameters = parameters + }); + } + } + + return NO_ERROR; + } + + public override CmsError PLC_RM156Data(ref List value) + { + // NB: da verificare se sia corretto o meno come BIT ARRAY... + + byte val = 0; + List vals = new List(); + CmsError libraryError = MEM_RWByte(R, false, 0, M156_INPUT_NEEDED.MemType, M156_INPUT_NEEDED.Address, M156_INPUT_NEEDED.SubAddress, 0, ref val); + if (libraryError.IsError()) + return libraryError; + + libraryError = MEM_RWByteList(R, 0, M156_INPUT_ID_LIST.MemType, M156_INPUT_ID_LIST.Address, M156_INPUT_ID_LIST.SubAddress, 0, M156_INPUT_ID_LIST.Size, ref vals); + if (libraryError.IsError()) + return libraryError; + + bool[] bits = ByteToBits(val); + + // FORZO: 1 solo processo + //for (int processId = 1; processId <= MAX_PROCESS_NUMBER; processId++) + for (int processId = 1; processId <= 1; processId++) + { + if (bits[processId - 1]) + { + // leggo x compatibilità la risposta standard + double responseVal = 0; + // Read machine variable + libraryError = MEM_RWDouble(R, 0, M156_RESPONSE_MEMORY.MemType, M156_RESPONSE_MEMORY.Address, M156_RESPONSE_MEMORY.SubAddress + (int)processId - 1, ref responseVal); + if (libraryError.IsError()) + return libraryError; + // Parse line & get parameters + value.Add(new M156InputIsNeededModel() + { + Process = (uint)processId, + Id = vals.ElementAt(processId - 1), + Value = responseVal + }); + } + } + + return NO_ERROR; + } + + // MACHINE COUNTERS + public override CmsError PLC_RMachineCounters(ref List counters) + { + List val = new List(); + // Read ints + CmsError libraryError = MEM_RWDWordList(R, 0, COUNTERS_DATA.MemType, COUNTERS_DATA.Address, COUNTERS_DATA.SubAddress, COUNTERS_DATA.Size / 4, ref val); + if (libraryError.IsError()) + return libraryError; + + // Set return value + uint i = 0; + counters = val.Select(x => new CounterModel() + { + Id = i++, + Value = x + }) + .ToList(); + + return NO_ERROR; + } + + /// + /// Get current Modules Block list + /// + /// updates only RT parameters (false = update all) + /// + /// + public override CmsError PLC_RModulesBlockList(bool onlyRT, ref Dictionary currModulesBlockList) + { + // se richiesto NON SOLO RT faccio refresh anche dati "lenti" + if (!onlyRT) + { + refreshMemModBlockParameter(); + } + // refresh dati veloci / RT + refreshMemModBlockParameterRT(); + + // copio lista act in output... + currModulesBlockList = ThermoModuleList; + return NO_ERROR; + } + + public override CmsError PLC_ROperatorInputIsNeeded(ref List value) + { + return FUNCTION_NOT_ALLOWED_ERROR; } public override CmsError PLC_RPowerOnData(ref PreAndPostPowerOnModel powerOnModel) @@ -734,375 +3683,93 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } - public override CmsError PLC_WPowerOnData(uint id, bool value) + /// + /// Get current Production Cycle data + /// + /// + /// + public override CmsError PLC_RProdCycle(ref ThermoModels.ProdCycleModel currProdCycle) { - // Check bit range - if (id > 16) - return INCORRECT_PARAMETERS_ERROR; - - // Call restore message - CmsError libraryError = PLC_WStrobe(false, PRE_POST_POWER_ON_ACK, PRE_POST_POWER_ON_CLICKED, id); + List currMem = new List(); + CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_CYCLE.MemType, PROCESS_PROD_CYCLE.Address, PROCESS_PROD_CYCLE.SubAddress, 0, PROCESS_PROD_CYCLE.Size, ref currMem); if (libraryError.IsError()) return libraryError; + // converto! + currProdCycle = new ThermoModels.ProdCycleModel() + { + Status = S7.Net.Types.Word.FromByteArray(currMem.Skip(0).Take(2).ToArray()), + MessageId = S7.Net.Types.Word.FromByteArray(currMem.Skip(2).Take(2).ToArray()), + Mode = S7.Net.Types.Byte.FromByteArray(currMem.Skip(4).Take(1).ToArray()), + Submode = S7.Net.Types.Byte.FromByteArray(currMem.Skip(5).Take(1).ToArray()), + TimeAdv = S7.Net.Types.DWord.FromByteArray(currMem.Skip(6).Take(4).ToArray()) + }; + return NO_ERROR; } - public override CmsError PLC_RFunctionAccess(ref List functions) + /// + /// Get current Production Info data + /// + /// + /// + /// + public override CmsError PLC_RProdInfo(ref ThermoModels.ProdInfoModel currProdInfo) { - List readValues = new List(); - int numberOfIntegers = FUNCTION_ACCESS.Size / 4; - // Read functions access data from memory - CmsError libraryError = MEM_RWIntegerList(R, 0, FUNCTION_ACCESS.MemType, FUNCTION_ACCESS.Address, FUNCTION_ACCESS.SubAddress, numberOfIntegers, ref readValues); + List currMem = new List(); + CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem); if (libraryError.IsError()) return libraryError; - 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++) + // converto! + currProdInfo = new ThermoModels.ProdInfoModel() { - functions.Add(new FunctionalityModel() - { - Id = (uint)i + 1, - // forzo a true perché non gestita dal PLC - IsActive = true //bits[i] - }); + NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()), + NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()), + TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()), + TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()), + TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()), + TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()), + TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()), + MaterialTempEndWarm = S7.Net.Types.Real.FromByteArray(currMem.Skip(26).Take(4).ToArray()), + MaterialTempEndVent = S7.Net.Types.Real.FromByteArray(currMem.Skip(30).Take(4).ToArray()), + MoldTemp = S7.Net.Types.Real.FromByteArray(currMem.Skip(34).Take(4).ToArray()), + VacuumReadVal = S7.Net.Types.Real.FromByteArray(currMem.Skip(38).Take(4).ToArray()), + MouldEnergyOUT = S7.Net.Types.Real.FromByteArray(currMem.Skip(42).Take(4).ToArray()), + MouldEnergyIN = S7.Net.Types.Real.FromByteArray(currMem.Skip(46).Take(4).ToArray()), + NumPreHot = S7.Net.Types.Int.FromByteArray(currMem.Skip(50).Take(2).ToArray()) + }; + + return NO_ERROR; + } + + /// + /// read current recipe parameter list + /// + /// updates only RT parameters (false = update all) + /// + /// + public override CmsError PLC_RRecipeParamList(bool onlyRT, ref Dictionary currParamList) + { + CmsError currError = NO_ERROR; + // refresh dati veloci / RT + refreshMemRecipeParameterRT(); + // se richiesto NON SOLO RT faccio refresh anche dati "lenti" + if (!onlyRT) + { + refreshMemRecipeParameter(); } - return NO_ERROR; + // copio lista act in output... + currParamList = ThermoParamList; + return currError; } - public override CmsError PLC_RAxesResetData(ref AxisResetDataModel axisResetData) - { - byte value = 0; - // Read byte from memory - CmsError libraryError = MEM_RWByte(R, true, 0, AXIS_RESET_PROCEDURE.MemType, AXIS_RESET_PROCEDURE.Address, AXIS_RESET_PROCEDURE.SubAddress, 0, ref value); - if (libraryError.IsError()) - return libraryError; - - // 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_RUserSoftKeys(ref List softKeys) - { - CmsError libraryError = PLC_RSoftKeys(USER_SOFTKEYS_VALUE, USER_SOFTKEYS_CLICKABLE, ref softKeys); - if (libraryError.IsError()) - return libraryError; - - 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 libraryError = MEM_RWIntegerList(R, 0, - softKeyStatusMemory.MemType, - softKeyStatusMemory.Address, - softKeyStatusMemory.SubAddress, - memorySizeToRead / 4, - ref readValues); - - if (libraryError.IsError()) - return libraryError; - - // need byte swap! - List fixValues = new List(); - foreach (var item in readValues) - { - fixValues.Add(SwapBytes(item)); - } - // Convert ints into an array of bools - bool[] bits = IntToBits(fixValues.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_WUserSoftKey(uint id) - { - // Check id range - if (id > USER_SOFTKEYS_NUMBER) - return INCORRECT_PARAMETERS_ERROR; - - // Write strobe into memory --> false because is bitArray - CmsError libraryError = PLC_WStrobe(false, USER_SOFT_KEYS_ACK, USER_SOFT_KEYS_CLICKED, id); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - - public override CmsError PLC_RHeadsData(List heads, int number) + public override CmsError PLC_RScadaSiemens(ref List objects) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError PLC_RWorkedTimeHead(int head, ref uint time) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError PLC_WResetWorkedTimeHead(int head) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError PLC_RWorkedTimeMachine(ref uint time) - { - // Read Worked time - CmsError libraryError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - - public override CmsError PLC_WResetWorkedTimeMachine(uint time) - { - //FIXME TODO verificare endianness aree memoria - - uint actTime = 0; - - // Read actual Value - CmsError libraryError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref actTime); - if (libraryError.IsError()) - return libraryError; - - // 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; - libraryError = MEM_RWBoolean(W, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue); - if (libraryError.IsError()) - return libraryError; - - //Aspetto che venga abbassato - do - { - Thread.Sleep(50); - nTry += 1; - libraryError = MEM_RWBoolean(R, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue); - if (libraryError.IsError()) - return libraryError; - - } while (bitValue && nTry <= 10); - - //se il valore è rimasto a 1 il plc non l'ha preso in carico, e abortisco - if (bitValue) - { - bitValue = true; - libraryError = MEM_RWBoolean(W, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue); - if (libraryError.IsError()) - return libraryError; - - return PLC_NOT_RUNNING_ERROR; - } - else - { - //Se l'ha abbassato scrivo il nuovo dato - libraryError = 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) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - // MACHINE COUNTERS - public override CmsError PLC_RMachineCounters(ref List counters) - { - List val = new List(); - // Read ints - CmsError libraryError = MEM_RWDWordList(R, 0, COUNTERS_DATA.MemType, COUNTERS_DATA.Address, COUNTERS_DATA.SubAddress, COUNTERS_DATA.Size / 4, ref val); - if (libraryError.IsError()) - return libraryError; - - // 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) - { - // FIXME TODO verifica se endianness vada gestita o meno (qui FALSE) - bool isResettable = false; - CmsError libraryError = MEM_RWBoolean(R, false, 0, COUNTER_IS_RESETTABLE.MemType, COUNTER_IS_RESETTABLE.Address, COUNTER_IS_RESETTABLE.SubAddress, (int)(counter - 1), ref isResettable); - if (libraryError.IsError()) - return libraryError; - - if (!isResettable) - return FUNCTION_NOT_ALLOWED_ERROR; - - libraryError = PLC_WStrobe(false, COUNTER_IS_RESETTABLE_ACK, COUNTER_IS_RESETTABLE_STROBE, counter); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - - public override CmsError PLC_ROperatorInputIsNeeded(ref List value) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError PLC_WOperatorInputResponse(int process, double responseVal) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError PLC_RM154Data(ref List data, ref bool MTCOnOff) - { - // FIXME TODO - levare? inserito anche endiannes - - MTCOnOff = false; - CmsError libraryError = MEM_RWBoolean(R, true, 0, M154_SWITCH_ONOFF.MemType, M154_SWITCH_ONOFF.Address, M154_SWITCH_ONOFF.SubAddress, 1, ref MTCOnOff); - - if (libraryError.IsError()) - return libraryError; - - byte val = 0; - libraryError = MEM_RWByte(R, true, 0, M154_STROBE.MemType, M154_STROBE.Address, M154_STROBE.SubAddress, 0, ref val); - if (libraryError.IsError()) - return libraryError; - - // 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 - libraryError = PROC_ReadActiveLine(processId, ref tmpStr); - if (libraryError.IsError()) - return libraryError; - - // 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, true); - } - - public override CmsError PLC_RM156Data(ref List value) - { - // NB: da verificare se sia corretto o meno come BIT ARRAY... - - byte val = 0; - List vals = new List(); - CmsError libraryError = MEM_RWByte(R, false, 0, M156_INPUT_NEEDED.MemType, M156_INPUT_NEEDED.Address, M156_INPUT_NEEDED.SubAddress, 0, ref val); - if (libraryError.IsError()) - return libraryError; - - libraryError = MEM_RWByteList(R, 0, M156_INPUT_ID_LIST.MemType, M156_INPUT_ID_LIST.Address, M156_INPUT_ID_LIST.SubAddress, 0, M156_INPUT_ID_LIST.Size, ref vals); - if (libraryError.IsError()) - return libraryError; - - bool[] bits = ByteToBits(val); - - // FORZO: 1 solo processo - //for (int processId = 1; processId <= MAX_PROCESS_NUMBER; processId++) - for (int processId = 1; processId <= 1; processId++) - { - if (bits[processId - 1]) - { - // leggo x compatibilità la risposta standard - double responseVal = 0; - // Read machine variable - libraryError = MEM_RWDouble(R, 0, M156_RESPONSE_MEMORY.MemType, M156_RESPONSE_MEMORY.Address, M156_RESPONSE_MEMORY.SubAddress + (int)processId - 1, ref responseVal); - if (libraryError.IsError()) - return libraryError; - // Parse line & get parameters - value.Add(new M156InputIsNeededModel() - { - Process = (uint)processId, - Id = vals.ElementAt(processId - 1), - Value = responseVal - }); - } - } - - return NO_ERROR; - } - - public override CmsError PLC_WM156Response(int process, double responseVal) - { - // forzo process a 1... - process = 1; - CmsError libraryError = MEM_RWDouble(W, 0, M156_RESPONSE_MEMORY.MemType, M156_RESPONSE_MEMORY.Address, M156_RESPONSE_MEMORY.SubAddress + (int)process - 1, ref responseVal); - if (libraryError.IsError()) - return libraryError; - - // FIXME TODO verifica se endianness vada gestita o meno (qui FALSE) - return PLC_WStrobe(false, 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) @@ -1177,816 +3844,6 @@ namespace CMS_CORE_Library.S7Net return libraryError; } - public override CmsError PLC_RScadaSiemens(ref List objects) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value) - { - string[] index = memIndex.Split('.'); - CmsError libraryError = 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); - libraryError = 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); - libraryError = 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); - libraryError = 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); - libraryError = MEM_RWByte(W, true, 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); - libraryError = MEM_RWBoolean(W, false, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val); - } - - return libraryError; - } - - 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; - } - /// - /// Write strobe and manage ack from PLC - /// - /// Apply endianness swap (word=yes, bitArray=no) - /// - /// - /// - /// - private CmsError PLC_WStrobe(bool fixEndian, MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id) - { - CmsError libraryError; - bool readValue = false; - bool writeValue = true; - - SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId); - - // Check Strobe - libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); - if (libraryError.IsError()) - return libraryError; - - // se è true - int n = 200; - do - { - // Check Strobe - libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); - Thread.Sleep(20); - n--; - } while (n > 0 && readValue); - - // If PLC is true --> reset - if (readValue) - { - bool forceVal = false; - libraryError = MEM_RWBoolean(W, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref forceVal); - } - - // Check ACK - libraryError = MEM_RWBoolean(R, fixEndian, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue); - if (libraryError.IsError()) - return libraryError; - - // If PLC it's performing another request then return - if (readValue) - return NO_ERROR; - - // Write strobe into memory - libraryError = MEM_RWBoolean(W, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref writeValue); - if (libraryError.IsError()) - return libraryError; - - // Reset wait ack = 1 and reset the strobe - libraryError = ResetStrobe(alarmBitId, strobeByte, ackByte, ackCell.MemType, fixEndian); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - /// - /// Write ack for strobe received from PLC - /// - /// Apply endianness swap (word=yes, bitArray=no) - /// - /// - /// - /// - private CmsError PLC_WAck(bool fixEndian, MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id) - { - CmsError libraryError; - bool readValue = false; - bool writeValue = true; - - SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId); - - // Check Strobe - libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue); - if (libraryError.IsError()) - return libraryError; - - // if there's a strobe --> give ack!!! - if (readValue) - { - // abbasso ack se fosse su... - libraryError = MEM_RWBoolean(W, fixEndian, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref writeValue); - if (libraryError.IsError()) - return libraryError; - - // attendo 50ms... - Thread.Sleep(50); - - // Reset wait ack = 1 and reset the strobe - libraryError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType, fixEndian); - if (libraryError.IsError()) - return libraryError; - - // exit and next round will continue... - return NO_ERROR; - } - - return NO_ERROR; - } - /// - /// Setup memory for ack/strobe processing - /// - /// base addr for ack zone - /// base addr for strobe zone - /// parameters to set (id 1...n) - /// ack byte to use (OUT) - /// strobe byte to use (out) - /// bit 1..8 - 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, bool fixEndian) - { - int n = 200; - bool readValue = false; - bool writeValue = false; - bool ok = false; - - CmsError libraryError; - do - { - // Check ACK - libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, TABLE, ackByte, bitId, ref readValue); - if (libraryError.IsError()) - return libraryError; - - // If true reset strobe - if (readValue == true) - { - // Reset strobe - libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, strobeByte, bitId, ref writeValue); - if (libraryError.IsError()) - return libraryError; - // Exit from cycle - n = 0; - ok = true; - } - else - { - // Decrement - n--; - // Wait befor next cycle - Thread.Sleep(20); - } - } while (n > 0); - - if (!ok) - { - writeValue = false; - // Reset strobe - libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, strobeByte, bitId, ref writeValue); - if (libraryError.IsError()) - return libraryError; - } - - return libraryError; - } - private CmsError ResetAck(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType, bool fixEndian) - { - int n = 600; - bool readValue = false; - bool writeValue = false; - bool ok = false; - - // aspetto 100ms - Thread.Sleep(100); - - CmsError libraryError; - do - { - // Check Strobe - libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, TABLE, strobeByte, bitId, ref readValue); - if (libraryError.IsError()) - return libraryError; - - // If false reset ACK - if (readValue == false) - { - // Reset strobe - libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, ackByte, bitId, ref writeValue); - if (libraryError.IsError()) - return libraryError; - // Exit from cycle - n = 0; - ok = true; - } - else - { - // Decrement - n--; - // Wait befor next cycle - Thread.Sleep(20); - } - } while (n > 0); - - - if (!ok) - { - // Reset ack (forced) - writeValue = false; - libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, TABLE, ackByte, bitId, ref writeValue); - if (libraryError.IsError()) - return libraryError; - } - - return libraryError; - } - - private CmsError PLC_ManageActiveAck(int strobeByte, int strobeSubByte, int strobeBit, int ackByte, int ackSubByte, int ackBit, MEMORY_TYPE memType, bool fixEndian) - { - int n = 1200; // 30 seconds - bool readValue = false; - bool writeValue = true; - bool ok = false; - // Set ack to 1 - CmsError libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue); - if (libraryError.IsError()) - return libraryError; - - do - { - // Check strobe - libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, strobeByte, strobeSubByte, strobeBit, ref readValue); - if (libraryError.IsError()) - return libraryError; - - // If true reset acknowledge - if (!readValue) - { - writeValue = false; - // Reset acknowledge - libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue); - if (libraryError.IsError()) - return libraryError; - // 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; - libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue); - if (libraryError.IsError()) - return libraryError; - } - - return libraryError; - } - - public override CmsError PLC_WExpiredCandy(bool value) - { - bool newVal = false; - - //Scrivo il dato - CmsError libraryError = MEM_RWBoolean(W, true, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value); - if (libraryError.IsError()) - return libraryError; - else - { - //Leggo il dato - libraryError = PLC_RExpiredCandy(ref newVal); - if (libraryError.IsError()) - return libraryError; - - //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 libraryError = MEM_RWBoolean(R, true, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value); - if (libraryError.IsError()) - return libraryError; - 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 libraryError = MEM_RWWord(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word); - if (libraryError.IsError()) - return libraryError; - - int integer = (int)((value & 0xFFFFFFFF0000) >> 16); - // Write Integer (+1 is used because osai uses word) - libraryError = MEM_RWInteger(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref integer); - if (libraryError.IsError()) - return libraryError; - - // Rieggo il dato - long newVal = 0; - libraryError = PLC_RCandy(ref newVal); - if (libraryError.IsError()) - return libraryError; - - // 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 libraryError = MEM_RWWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word); - if (libraryError.IsError()) - return libraryError; - - // Read first int - uint firtInt = 0; - libraryError = MEM_RWDWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref firtInt); - if (libraryError.IsError()) - return libraryError; - - - - // Build Long value - value = ((long)firtInt << 16) + word; - - return NO_ERROR; - } - - public override CmsError PLC_RActiveClient(ref int clientId) - { - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - byte readValues = 0; - libraryError = MEM_RWByte(R, true, 0, ACTIVE_CLIENT.MemType, ACTIVE_CLIENT.Address, ACTIVE_CLIENT.SubAddress, 0, ref readValues); - if (libraryError.IsError()) - return libraryError; - - // 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 libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - // FIXME TODO - fare guardando mappatura memoria stsato processo - -#if false - // 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); - } -#endif - - 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 libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - - // FIXME TODO - fare guardando mappatura variabili status -#if false - // 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); - } -#endif - - return NO_ERROR; - } - - // Get PP Lines - public override CmsError PROC_RPPLines(ushort ProcNumber, ref List Lines) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - // Get PP Name - public override CmsError PROC_RSelectedPPName(ushort ProcNumber, ref string Name) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - // Get the process Active Alarms - public override CmsError PROC_RActiveAlarms(ushort procNumber, ref List alarms) - { - // FIXME TODO - fare guardando bitmap allarmi attivi -#if false - 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(); -#endif - - return NO_ERROR; - } - - // Get process part program data - public override CmsError PROC_RStatusAndData(ushort procNumber, ref ProcessDataModel processData) - { - processData.Id = procNumber; - CmsError libraryError = NO_ERROR; -#if false - // Read part program name - libraryError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName); - if (libraryError.IsError()) - return libraryError; -#endif - - // FIXME TODO --> forzato tutto a true... eventualmente rivedere in futuro x processo caricatore vs processo principale - bool forceValues = true; - - if (forceValues) - { - processData.Visible = true; - processData.Type = "WORK"; - processData.IsSelected = true; - processData.IsInAlarm = false; - processData.CanLoadProgram = true; - processData.Status = "RUN"; - processData.Reps = 0; - } - else - { - int readValue = 0; - - // Read processes status from memory - libraryError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address, PROCESS_STATUS.SubAddress + ((procNumber - 1) * 2), ref readValue); - if (libraryError.IsError()) - return libraryError; - - 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 libraryError; - //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 - // libraryError = MEM_RWBoolean(R, 0, SELECTED_PROCESS.MemType, SELECTED_PROCESS.Address, memoryAddress, 2, ref readValue); - // if (libraryError.IsError()) - // return libraryError; - - // if (readValue) - // { - // procNumber = (ushort)(i + 1); - // return NO_ERROR; - // } - //} - - return NO_ERROR; - } - - public override CmsError PROC_WSelectProcess(ushort procNumber) - { - CmsError libraryError; - byte processNum = (byte)procNumber; - - // Check parameter - if (processNum > MAX_PROCESS_NUMBER) - return INCORRECT_PARAMETERS_ERROR; - - // Write process number - libraryError = MEM_RWByte(W, true, 0, SELECT_PROCESS.MemType, SELECT_PROCESS.Address, SELECT_PROCESS.SubAddress, 0, ref processNum); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - - public override CmsError PROC_RSelectedProcessData(int processId, ref SelectedProcessData processData) - { - if (processId <= 0) - return PROC_NOT_FOUND_ERROR; - - // FIXME TODO - ha senso? -#if false - 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); - } -#endif - - return NO_ERROR; - } - - private CmsError PROC_ReadActiveLine(uint processId, ref string line) - { - return FUNCTION_NOT_ALLOWED_ERROR; - - } - - #endregion PROCESS (PATH) High-level data - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - #region THERMO high level data - - /// /// Read Status/command words /// @@ -2002,36 +3859,357 @@ namespace CMS_CORE_Library.S7Net return libraryError; } + + public override CmsError PLC_RToolMovement(ref MovementBetweenMagazinesModel toolMovement) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PLC_RUserSoftKeys(ref List softKeys) + { + CmsError libraryError = PLC_RSoftKeys(USER_SOFTKEYS_VALUE, USER_SOFTKEYS_CLICKABLE, ref softKeys); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + /// - /// Process conf request for RISK data + /// Get current Warmers Channels list /// + /// updates only READ parameters (false = update all data) + /// /// - public override CmsError PLC_WAckConfRiskRequest() + public override CmsError PLC_RWarmerChannelList(bool useCache, ref Dictionary currWarmerChannelList) + { + // refresh stato canale ESP[i] + refreshRiscStatus(); + // refresh % lavoro attuale OVp[i] + refreshRiscPerc(); + // refresh corrente attuale Ich[i] + refreshRiscActCurr(); + // refresh setpoint PLC % (era 514 --> 627) + refreshRiscSetpointPLC(); + + // refresh dati status/comando termocamera + refreshRiscTermoCamCommStatus(); + + // refresh setpoint HMI canale % | Write + refreshRiscSetpointHMI(); + + if (!useCache) + { + // refresh abilitazione canale x thermoCam | Write + refreshRiscTermoCamEnab(); + // refresh ultima temp canale letta da thermoCam | Write + refreshRiscTermoCamTempAct(); + // refresh temp canale impostata x thermoCam | Write + refreshRiscTermoCamTempSet(); + } + + // copio lista act in output + currWarmerChannelList = ThermoWarmChannels; + + return NO_ERROR; + } + + /// + /// Get current Warmers VUMin data + /// + /// + /// + public override CmsError PLC_RWarmerConfVUMin(ref ushort VUmin) + { + // leggo da 513.0 --> default 210 + VUmin = 230; + List currMem = new List(); + + // read actual data on memory... + CmsError libraryError = MEM_RWWord(R, 0, RISC_VU_MIN.MemType, RISC_VU_MIN.Address, RISC_VU_MIN.SubAddress, ref VUmin); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + /// + /// Get current Warmers ThermoCam Data + /// + /// + /// + public override CmsError PLC_RWarmerTCamData(out ThermoModels.ThermoCam currTCamData) + { + // init... + bool currValue = false; + currTCamData = new ThermoModels.ThermoCam(); + + // leggo da PLC singoli bit... + CmsError libraryError = MEM_RWBoolean(R, true, 0, TCAM_STATW_DATA.MemType, TCAM_STATW_DATA.Address, TCAM_STATW_DATA.SubAddress, 0, ref currValue); + if (libraryError.IsError()) + return libraryError; + + ThermoCamData.ThermoOptionActive = currValue; + + libraryError = MEM_RWBoolean(R, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 0, ref currValue); + if (libraryError.IsError()) + return libraryError; + + ThermoCamData.ThermoCamMode = currValue; + + libraryError = MEM_RWBoolean(R, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 1, ref currValue); + if (libraryError.IsError()) + return libraryError; + + ThermoCamData.ThermoCamOnOff = currValue; + + // restituisce status dei parametri termocamera (in cache...) + currTCamData = ThermoCamData; + + return libraryError; + } + + public override CmsError PLC_RWManageWatchdog() + { + // watchdog in memoria WORD --> true x endianness! + bool plcWatchdog = false; + CmsError libraryError = MEM_RWBoolean(R, true, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog); + if (libraryError.IsError()) + return libraryError; + + if (plcWatchdog) + return PLC_NOT_RUNNING_ERROR; + // tira su il bit... + plcWatchdog = true; + return MEM_RWBoolean(W, true, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog); + } + + public override CmsError PLC_RWorkedTimeHead(int head, ref uint time) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PLC_RWorkedTimeMachine(ref uint time) + { + // Read Worked time + CmsError libraryError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + /// + /// Write MULTIPLE Digital Out FORCED Status (bitmap) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public override CmsError PLC_W_IO_AO_Reset(Dictionary newValues) { CmsError libraryError = NO_ERROR; - // Call ack for config request RISK - libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 8); + List rwValuesAO = new List(); + + // leggo da PLC a array di byte di appoggio x visibilità AO... + libraryError = MEM_RWWordList(R, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref rwValuesAO); + if (libraryError.IsError()) + return libraryError; + + int bank = 0; + int pos = 0; + int size = 16; + // imposto i valori NUOVI... cerco il BANK da 16 bit... + foreach (var item in newValues) + { + bank = item.Key / size; + pos = item.Key % size; + // aggiorno + if (item.Value) + { + rwValuesAO[bank] = (ushort)(((int)rwValuesAO[bank]).SetBitOne(pos)); + } + else + { + rwValuesAO[bank] = (ushort)(((int)rwValuesAO[bank]).SetBitZero(pos)); + } + } + + // scrivo! + libraryError = MEM_RWWordList(W, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref rwValuesAO); if (libraryError.IsError()) return libraryError; return libraryError; } + /// - /// Process conf request for FLIR picture request + /// Write MULTIPLE Analog Out values (+ force) /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli /// - public override CmsError PLC_WAckFlirRequest() + public override CmsError PLC_W_IO_AO_Val(Dictionary newValues) + { + CmsError libraryError = NO_ERROR; + List rwValuesAO = new List(); + Dictionary newForced = new Dictionary(); + + // leggo da PLC valori AO... + libraryError = MEM_RWShortList(R, 0, IO_AO_VAL_FOR.MemType, IO_AO_VAL_FOR.Address, IO_AO_VAL_FOR.SubAddress, IO_AO_VAL_FOR.Size, ref rwValuesAO); + if (libraryError.IsError()) + return libraryError; + + // aggiorno valori ricevuti// imposto i valori NUOVI... cerco il BANK da 16 bit... + foreach (var item in newValues) + { + rwValuesAO[item.Key] = (short)item.Value; + newForced.Add(item.Key, true); + } + + // scrivo valori + libraryError = MEM_RWShortList(W, 0, IO_AO_VAL_FOR.MemType, IO_AO_VAL_FOR.Address, IO_AO_VAL_FOR.SubAddress, IO_AO_VAL_FOR.Size, ref rwValuesAO); + if (libraryError.IsError()) + return libraryError; + + // scrivo forced + PLC_W_IO_AO_Reset(newForced); + + return libraryError; + } + + /// + /// Write MULTIPLE Digital Out FORCED Status (bitmap) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public override CmsError PLC_W_IO_DO_Reset(Dictionary newValues) { CmsError libraryError = NO_ERROR; - // Call ack for config request RISK - libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 13); + List rwValuesDO = new List(); + + // leggo da PLC a array di byte di appoggio x visibilità DO... + libraryError = MEM_RWWordList(R, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref rwValuesDO); + if (libraryError.IsError()) + return libraryError; + + int bank = 0; + int pos = 0; + int size = 16; + // imposto i valori NUOVI... cerco il BANK da 16 bit... + foreach (var item in newValues) + { + bank = item.Key / size; + pos = item.Key % size; + // aggiorno + if (item.Value) + { + rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitOne(pos)); + } + else + { + rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitZero(pos)); + } + } + + // scrivo! + libraryError = MEM_RWWordList(W, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref rwValuesDO); if (libraryError.IsError()) return libraryError; return libraryError; } + + /// + /// Write MULTIPLE Digital Out values (+ force) + /// + /// Oggetto valori da aggiornare (from HMI) + /// num max parametri da scrivere singolarmente + /// delay in scriottura multi parametri singoli + /// + public override CmsError PLC_W_IO_DO_Val(Dictionary newValues) + { + CmsError libraryError = NO_ERROR; + List rwValuesDO = new List(); + Dictionary newForced = new Dictionary(); + + // leggo da PLC valori DO... + libraryError = MEM_RWWordList(R, 0, IO_DO_VAL_FOR.MemType, IO_DO_VAL_FOR.Address, IO_DO_VAL_FOR.SubAddress, IO_DO_VAL_FOR.Size, ref rwValuesDO); + if (libraryError.IsError()) + return libraryError; + + int bank = 0; + int pos = 0; + int size = 16; + // imposto i valori NUOVI... cerco il BANK da 16 bit... + foreach (var item in newValues) + { + bank = item.Key / size; + pos = item.Key % size; + // aggiorno + if (item.Value) + { + rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitOne(pos)); + } + else + { + rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitZero(pos)); + } + newForced.Add(item.Key, true); + } + + // scrivo! + libraryError = MEM_RWWordList(W, 0, IO_DO_VAL_FOR.MemType, IO_DO_VAL_FOR.Address, IO_DO_VAL_FOR.SubAddress, IO_DO_VAL_FOR.Size, ref rwValuesDO); + if (libraryError.IsError()) + return libraryError; + + // scrivo forced + PLC_W_IO_DO_Reset(newForced); + + return libraryError; + } + + /// + /// Reset ALL DO / AO forced bitmap + /// + /// + public override CmsError PLC_W_IO_ResetAll() + { + CmsError libraryError = NO_ERROR; + + List writeValuesDO = new List(); + List writeValuesAO = new List(); + // imposto a zero... + for (int i = 0; i < IO_DO_FORCE.Size; i++) + { + writeValuesDO.Add(0); + } + for (int i = 0; i < IO_AO_FORCE.Size; i++) + { + writeValuesAO.Add(0); + } + + // scrivo su PLC + libraryError = MEM_RWWordList(W, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref writeValuesDO); + if (libraryError.IsError()) + return libraryError; + // scrivo su PLC + libraryError = MEM_RWWordList(W, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref writeValuesAO); + if (libraryError.IsError()) + return libraryError; + + return libraryError; + } + + 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, true); + } + /// /// Process conf request /// @@ -2047,6 +4225,40 @@ namespace CMS_CORE_Library.S7Net return libraryError; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// Process conf request for RISK data + /// + /// + public override CmsError PLC_WAckConfRiskRequest() + { + CmsError libraryError = NO_ERROR; + + // Call ack for config request RISK + libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 8); + if (libraryError.IsError()) + return libraryError; + + return libraryError; + } + + /// + /// Process conf request for FLIR picture request + /// + /// + public override CmsError PLC_WAckFlirRequest() + { + CmsError libraryError = NO_ERROR; + + // Call ack for config request RISK + libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 13); + if (libraryError.IsError()) + return libraryError; + + return libraryError; + } + /// /// Process production info update /// @@ -2062,21 +4274,7 @@ namespace CMS_CORE_Library.S7Net return libraryError; } - /// - /// Process start prod ack - /// - /// - public override CmsError PLC_WAckPzProdStart() - { - CmsError libraryError = NO_ERROR; - // Call ack for prod update - libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 11); - if (libraryError.IsError()) - return libraryError; - - return libraryError; - } /// /// Process end prod ack /// @@ -2093,6 +4291,22 @@ namespace CMS_CORE_Library.S7Net return libraryError; } + /// + /// Process start prod ack + /// + /// + public override CmsError PLC_WAckPzProdStart() + { + CmsError libraryError = NO_ERROR; + + // Call ack for prod update + libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 11); + if (libraryError.IsError()) + return libraryError; + + return libraryError; + } + /// /// Process setpointHMI invalidated with ack /// @@ -2109,137 +4323,234 @@ namespace CMS_CORE_Library.S7Net return libraryError; } - /// - /// Get current Axis RT data - /// - /// - /// - public override CmsError PLC_RAxisRTList(ref Dictionary currAxisRT) + public override CmsError PLC_WAssistedToolingCmd(ushort toolId, ushort familyId, ushort shankId, ushort magazineId, ushort positionId, ASSISTED_TOOLING_ACTION action) { - CmsError libraryError = NO_ERROR; - List currMem = new List(); - int packSize = 12; + return FUNCTION_NOT_ALLOWED_ERROR; + } - // leggo da PLC a array di byte di appoggio... - libraryError = MEM_RWByteList(R, 0, AXES_RTDATA.MemType, AXES_RTDATA.Address, AXES_RTDATA.SubAddress, 0, AXES_RTDATA.Size, ref currMem); + public override CmsError PLC_WCandy(long value) + { + // Long is formed by a integer + word + // Write Word + ushort word = (ushort)((value & 0xFFFF)); + CmsError libraryError = MEM_RWWord(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word); if (libraryError.IsError()) return libraryError; - // controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < AXES_RTDATA.Size / packSize; i++) - { - ThermoModels.AxisRT currData = new ThermoModels.AxisRT(i + 1, memArray.Skip(i * packSize).Take(packSize).ToArray()); - // solo se ID > 0... - if (currData.Id > 0) - { - // update oggetto thermoParamList... - if (currAxisRT.ContainsKey(currData.Id)) - { - try - { - currAxisRT[currData.Id].Position = currData.Position; - currAxisRT[currData.Id].Speed = currData.Speed; - currAxisRT[currData.Id].Load = currData.Load; - } - catch - { } - } - else - { - try - { - currAxisRT.Add(currData.Id, currData); - } - catch - { } - } - } - } - } - return libraryError; - } - /// - /// Get current Axis Info data - /// - /// - /// - public override CmsError PLC_RAxisInfoList(ref Dictionary currAxisInfo) - { - CmsError libraryError = NO_ERROR; -#if false - CmsError libraryError = NO_ERROR; - 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); + int integer = (int)((value & 0xFFFFFFFF0000) >> 16); + // Write Integer (+1 is used because osai uses word) + libraryError = MEM_RWInteger(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref integer); 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; + // Rieggo il dato + long newVal = 0; + libraryError = PLC_RCandy(ref newVal); + if (libraryError.IsError()) + return libraryError; + + // Se i 2 dati coincidono ritorno OK + if (value == newVal) + return NO_ERROR; + else + return PLC_NOT_RUNNING_ERROR; } - /// - /// read current recipe parameter list - /// - /// updates only RT parameters (false = update all) - /// - /// - public override CmsError PLC_RRecipeParamList(bool onlyRT, ref Dictionary currParamList) + + public override CmsError PLC_WExpiredCandy(bool value) { - CmsError currError = NO_ERROR; - // refresh dati veloci / RT - refreshMemRecipeParameterRT(); - // se richiesto NON SOLO RT faccio refresh anche dati "lenti" - if (!onlyRT) + bool newVal = false; + + //Scrivo il dato + CmsError libraryError = MEM_RWBoolean(W, true, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value); + if (libraryError.IsError()) + return libraryError; + else { - refreshMemRecipeParameter(); + //Leggo il dato + libraryError = PLC_RExpiredCandy(ref newVal); + if (libraryError.IsError()) + return libraryError; + + //Se i 2 dati coincidono ritorno OK + if (value == newVal) + return NO_ERROR; + else + return PLC_NOT_RUNNING_ERROR; + } + } + + public override CmsError PLC_WHeadOverride(uint id, HEAD_OVERRIDE_SIGN sign) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + /// + /// Set Keyboard softkey ID + /// + /// Softkey ID of the first button + /// Softkey ID of the second button + /// + public override CmsError PLC_WKeyboardSoftkey(ushort idKey1, ushort idKey2) + { + List currMem = new List(); + currMem.Add(idKey1); + currMem.Add(idKey2); + CmsError libraryError = MEM_RWWordList(W, 0, KEYBOARD_STAR_MEMORY.MemType, KEYBOARD_STAR_MEMORY.Address, KEYBOARD_STAR_MEMORY.SubAddress, KEYBOARD_STAR_MEMORY.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + public override CmsError PLC_WM156Response(int process, double responseVal) + { + // forzo process a 1... + process = 1; + CmsError libraryError = MEM_RWDouble(W, 0, M156_RESPONSE_MEMORY.MemType, M156_RESPONSE_MEMORY.Address, M156_RESPONSE_MEMORY.SubAddress + (int)process - 1, ref responseVal); + if (libraryError.IsError()) + return libraryError; + + // FIXME TODO verifica se endianness vada gestita o meno (qui FALSE) + return PLC_WStrobe(false, M156_INPUT_ACK, M156_INPUT_STROBE, (uint)process); + } + + /// + /// Request for mode selection via strobe + /// + /// 1: MAN, 2: AUTO, 3: SETUP + /// + public override CmsError PLC_WModeSel(int mode) + { + // se update --> scrivo strobe comando update... + if (mode == 1) + { + // Call confirm update + CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 6); + if (libraryError.IsError()) + return libraryError; + } + else + if (mode == 2) + { + // Call confirm update + CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 5); + if (libraryError.IsError()) + return libraryError; + } + else + if (mode == 3) + { + // Call confirm update + CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 7); + if (libraryError.IsError()) + return libraryError; } - // copio lista act in output... - currParamList = ThermoParamList; - return currError; + return NO_ERROR; } + + public override CmsError PLC_WOperatorInputResponse(int process, double responseVal) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PLC_WPowerOnData(uint id, bool value) + { + // Check bit range + if (id > 16) + return INCORRECT_PARAMETERS_ERROR; + + // Call restore message + CmsError libraryError = PLC_WStrobe(false, PRE_POST_POWER_ON_ACK, PRE_POST_POWER_ON_CLICKED, id); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + /// + /// Set ProdInfo data + /// + /// Qty requested (target) + /// Reset counter (actual counter) + /// Number of pre-warm cycle requested + /// + public override CmsError PLC_WProdInfo(short numTarget, bool doReset, short preWarmCycle) + { + List currMem = new List(); + CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + // converto! + var currProdInfo = new ThermoModels.ProdInfoModel() + { + NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()), + NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()), + PreWarmCycle = S7.Net.Types.Int.FromByteArray(currMem.Skip(4).Take(2).ToArray()), + TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()), + TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()), + TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()), + TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()), + TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()), + MaterialTempEndWarm = S7.Net.Types.Real.FromByteArray(currMem.Skip(26).Take(4).ToArray()), + MaterialTempEndVent = S7.Net.Types.Real.FromByteArray(currMem.Skip(30).Take(4).ToArray()), + MoldTemp = S7.Net.Types.Real.FromByteArray(currMem.Skip(34).Take(4).ToArray()), + VacuumReadVal = S7.Net.Types.Real.FromByteArray(currMem.Skip(38).Take(4).ToArray()), + MouldEnergyOUT = S7.Net.Types.Real.FromByteArray(currMem.Skip(42).Take(4).ToArray()), + MouldEnergyIN = S7.Net.Types.Real.FromByteArray(currMem.Skip(46).Take(4).ToArray()), + NumPreHot = S7.Net.Types.Int.FromByteArray(currMem.Skip(50).Take(2).ToArray()) + }; + + // aggiorno... + currProdInfo.NumTarget = numTarget; + currProdInfo.PreWarmCycle = preWarmCycle; + // converto a byte... + List newMem = currProdInfo.convertToByte().ToList(); + // riscrivo!!!! + libraryError = MEM_RWByteList(W, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref newMem); + if (libraryError.IsError()) + return libraryError; + + if (doReset) + { + // send strobe of NEW WorkOrder / reset QTY + libraryError = PLC_WStrobe(true, PROD_ACK, PROD_STROBE, 10); + if (libraryError.IsError()) + return libraryError; + } + + return NO_ERROR; + } + + /// + /// Confirm/Cancel recipe modifications + /// + /// true: HMI --> PLC, false: PLC --> HMI + /// + public override CmsError PLC_WRecipeEdit(bool confirmUpdate) + { + CmsError libraryError = NO_ERROR; + // se update --> scrivo strobe comando update... + if (confirmUpdate) + { + // Call confirm update + libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 2); + if (libraryError.IsError()) + return libraryError; + } + // altrimenti mando strobe comando cancel... + else + { + // Call cancel update + libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 3); + if (libraryError.IsError()) + return libraryError; + } + + return libraryError; + } + /// /// Write recipe updated MULTIPLE parameter /// @@ -2255,7 +4566,6 @@ namespace CMS_CORE_Library.S7Net int memIndex = 0; int packSize = 20; - // 2020.09.03: ricevuto da chiamata, dovrebbe essere 5 parametri x scrivere tutto (era 30 prima di 2008.08.07) bool writeSingle = newParameters.Count < nMaxParamWrite; @@ -2315,33 +4625,198 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } + /// - /// Confirm/Cancel recipe modifications + /// Send axis command /// - /// true: HMI --> PLC, false: PLC --> HMI + /// ID asse + /// Comando (0..15) + /// Indica se scrivere la TargetPos + /// Posizione target /// - public override CmsError PLC_WRecipeEdit(bool confirmUpdate) + public override CmsError PLC_WAxisCommand(int AxisNum, uint CommandBit, bool WritePos, double TargetPos) { CmsError libraryError = NO_ERROR; - // se update --> scrivo strobe comando update... - if (confirmUpdate) + + if (WritePos) { - // Call confirm update - libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 2); + MEMORY_CELL caTgtPos = new MEMORY_CELL(AXES_COMMAND.MemType, AXES_COMMAND.Address, AXES_COMMAND.SubAddress + ((AxisNum - 1) * 8), 2); + // in primis scrivo la TargetPos nei 4 byte DWord... + libraryError = MEM_RWDouble(W, 0, caTgtPos.MemType, caTgtPos.Address, caTgtPos.SubAddress, ref TargetPos); if (libraryError.IsError()) return libraryError; } - // altrimenti mando strobe comando cancel... - else + + // ...è permesso solo 0..7 + if (CommandBit >= 0 && CommandBit < 7) { - // Call cancel update - libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 3); + // posizione: è da array assi 0..n-1, 8byte ogni asse + MEMORY_CELL currAxAck = new MEMORY_CELL(AXES_COMMAND.MemType, AXES_COMMAND.Address, AXES_COMMAND.SubAddress + ((AxisNum - 1) * 8), 2); + MEMORY_CELL currAxStr = new MEMORY_CELL(AXES_COMMAND.MemType, AXES_COMMAND.Address, AXES_COMMAND.SubAddress + ((AxisNum - 1) * 8 + 2), 2); + + // Call confirm update + libraryError = PLC_WStrobe(true, currAxAck, currAxStr, CommandBit); if (libraryError.IsError()) return libraryError; } return libraryError; } + + public override CmsError PLC_WRefreshAllMessages() + { + // imposto come UserSoftKey + return PLC_WUserSoftKey(REFRESH_ALL_ALARMS_SFKEY_INDEX); + } + + public override CmsError PLC_WRefreshMessage(uint id) + { + // Check id range + if (id > ALARMS_NUMBER) + return INCORRECT_PARAMETERS_ERROR; + + // Call restore message: is a BIT ARRAY --> false! + CmsError libraryError = PLC_WStrobe(false, ALARM_ACK, ALARM_REFRESH_STROBE, id); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + public override CmsError PLC_WResetMachineCounters(uint counter) + { + // FIXME TODO verifica se endianness vada gestita o meno (qui FALSE) + bool isResettable = false; + CmsError libraryError = MEM_RWBoolean(R, false, 0, COUNTER_IS_RESETTABLE.MemType, COUNTER_IS_RESETTABLE.Address, COUNTER_IS_RESETTABLE.SubAddress, (int)(counter - 1), ref isResettable); + if (libraryError.IsError()) + return libraryError; + + if (!isResettable) + return FUNCTION_NOT_ALLOWED_ERROR; + + libraryError = PLC_WStrobe(false, COUNTER_IS_RESETTABLE_ACK, COUNTER_IS_RESETTABLE_STROBE, counter); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + public override CmsError PLC_WResetWorkedTimeHead(int head) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PLC_WResetWorkedTimeMachine(uint time) + { + //FIXME TODO verificare endianness aree memoria + + uint actTime = 0; + + // Read actual Value + CmsError libraryError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref actTime); + if (libraryError.IsError()) + return libraryError; + + // 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; + libraryError = MEM_RWBoolean(W, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue); + if (libraryError.IsError()) + return libraryError; + + //Aspetto che venga abbassato + do + { + Thread.Sleep(50); + nTry += 1; + libraryError = MEM_RWBoolean(R, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue); + if (libraryError.IsError()) + return libraryError; + } while (bitValue && nTry <= 10); + + //se il valore è rimasto a 1 il plc non l'ha preso in carico, e abortisco + if (bitValue) + { + bitValue = true; + libraryError = MEM_RWBoolean(W, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue); + if (libraryError.IsError()) + return libraryError; + + return PLC_NOT_RUNNING_ERROR; + } + else + { + //Se l'ha abbassato scrivo il nuovo dato + libraryError = 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_WRestoreMessage(uint id) + { + // Check id range + if (id > ALARMS_NUMBER) + return INCORRECT_PARAMETERS_ERROR; + + // Call restore message: is a BIT ARRAY --> true! + CmsError libraryError = PLC_WStrobe(true, ALARM_ACK, ALARM_RESTORATION_STROBE, id); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; + } + + public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value) + { + string[] index = memIndex.Split('.'); + CmsError libraryError = 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); + libraryError = 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); + libraryError = 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); + libraryError = 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); + libraryError = MEM_RWByte(W, true, 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); + libraryError = MEM_RWBoolean(W, false, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val); + } + + return libraryError; + } + /// /// Confirm FLIR image acquired and copied to PLC (STR from server) /// @@ -2357,1039 +4832,52 @@ namespace CMS_CORE_Library.S7Net } /// - /// Get current Modules Block list + /// Set ThermoCamera functionality active (HMI) /// - /// updates only RT parameters (false = update all) - /// + /// /// - public override CmsError PLC_RModulesBlockList(bool onlyRT, ref Dictionary currModulesBlockList) + public override CmsError PLC_WTCamActiv(bool enableTCam) { - // se richiesto NON SOLO RT faccio refresh anche dati "lenti" - if (!onlyRT) - { - refreshMemModBlockParameter(); - } - // refresh dati veloci / RT - refreshMemModBlockParameterRT(); - - // copio lista act in output... - currModulesBlockList = ThermoModuleList; - return NO_ERROR; - } - /// - /// Get current Warmers ThermoCam Data - /// - /// - /// - public override CmsError PLC_RWarmerTCamData(out ThermoModels.ThermoCam currTCamData) - { - // init... - bool currValue = false; - currTCamData = new ThermoModels.ThermoCam(); - - // leggo da PLC singoli bit... - CmsError libraryError = MEM_RWBoolean(R, true, 0, TCAM_STATW_DATA.MemType, TCAM_STATW_DATA.Address, TCAM_STATW_DATA.SubAddress, 0, ref currValue); - if (libraryError.IsError()) - return libraryError; - - ThermoCamData.ThermoOptionActive = currValue; - - libraryError = MEM_RWBoolean(R, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 0, ref currValue); - if (libraryError.IsError()) - return libraryError; - - ThermoCamData.ThermoCamMode = currValue; - - libraryError = MEM_RWBoolean(R, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 1, ref currValue); - if (libraryError.IsError()) - return libraryError; - - ThermoCamData.ThermoCamOnOff = currValue; - - // restituisce status dei parametri termocamera (in cache...) - currTCamData = ThermoCamData; - + CmsError libraryError = MEM_RWBoolean(W, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 1, ref enableTCam); return libraryError; } + /// - /// Get current Warmers Channels list + /// Set ThermoCamera mode /// - /// updates only READ parameters (false = update all data) - /// + /// /// - public override CmsError PLC_RWarmerChannelList(bool useCache, ref Dictionary currWarmerChannelList) + public override CmsError PLC_WTCamMode(bool enableTCam) { - // refresh stato canale ESP[i] - refreshRiscStatus(); - // refresh % lavoro attuale OVp[i] - refreshRiscPerc(); - // refresh corrente attuale Ich[i] - refreshRiscActCurr(); - // refresh setpoint PLC % (era 514 --> 627) - refreshRiscSetpointPLC(); - - // refresh dati status/comando termocamera - refreshRiscTermoCamCommStatus(); - - // refresh setpoint HMI canale % | Write - refreshRiscSetpointHMI(); - - if (!useCache) - { - // refresh abilitazione canale x thermoCam | Write - refreshRiscTermoCamEnab(); - // refresh ultima temp canale letta da thermoCam | Write - refreshRiscTermoCamTempAct(); - // refresh temp canale impostata x thermoCam | Write - refreshRiscTermoCamTempSet(); - } - - // copio lista act in output - currWarmerChannelList = ThermoWarmChannels; - - return NO_ERROR; - } - /// - /// Get gauge data - /// - /// - /// - public override CmsError PLC_RGaugeData(ref ThermoModels.LiveProdDataModel gaugeData) - { - List Values = new List(); - CmsError libraryError = MEM_RWIntegerList(R, 1, MACHINE_GAUGE_DATA.MemType, MACHINE_GAUGE_DATA.Address, MACHINE_GAUGE_DATA.SubAddress, MACHINE_GAUGE_DATA.Size / 4, ref Values); - - if (libraryError.IsError()) - return libraryError; - - gaugeData = new ThermoModels.LiveProdDataModel() - { - TimeAdv = Convert.ToUInt32(Values[0]), - Power = Values[1], - Vacuum = Values[2], - Air = Values[3], - }; - - return NO_ERROR; - } - /// - /// Set Keyboard softkey ID - /// - /// Softkey ID of the first button - /// Softkey ID of the second button - /// - public override CmsError PLC_WKeyboardSoftkey(ushort idKey1, ushort idKey2) - { - List currMem = new List(); - currMem.Add(idKey1); - currMem.Add(idKey2); - CmsError libraryError = MEM_RWWordList(W, 0, KEYBOARD_STAR_MEMORY.MemType, KEYBOARD_STAR_MEMORY.Address, KEYBOARD_STAR_MEMORY.SubAddress, KEYBOARD_STAR_MEMORY.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - /// - /// Get current Production Info data - /// - /// - /// - /// - public override CmsError PLC_RProdInfo(ref ThermoModels.ProdInfoModel currProdInfo) - { - List currMem = new List(); - CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - // converto! - currProdInfo = new ThermoModels.ProdInfoModel() - { - NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()), - NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()), - TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()), - TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()), - TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()), - TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()), - TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()), - MaterialTempEndWarm = S7.Net.Types.Double.FromByteArray(currMem.Skip(26).Take(4).ToArray()), - MaterialTempEndVent = S7.Net.Types.Double.FromByteArray(currMem.Skip(30).Take(4).ToArray()), - MoldTemp = S7.Net.Types.Double.FromByteArray(currMem.Skip(34).Take(4).ToArray()), - VacuumReadVal = S7.Net.Types.Double.FromByteArray(currMem.Skip(38).Take(4).ToArray()), - MouldEnergyOUT = S7.Net.Types.Double.FromByteArray(currMem.Skip(42).Take(4).ToArray()), - MouldEnergyIN = S7.Net.Types.Double.FromByteArray(currMem.Skip(46).Take(4).ToArray()), - NumPreHot = S7.Net.Types.Int.FromByteArray(currMem.Skip(50).Take(2).ToArray()) - }; - - return NO_ERROR; - } - /// - /// Set ProdInfo data - /// - /// Qty requested (target) - /// Reset counter (actual counter) - /// Number of pre-warm cycle requested - /// - public override CmsError PLC_WProdInfo(short numTarget, bool doReset, short preWarmCycle) - { - List currMem = new List(); - CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - // converto! - var currProdInfo = new ThermoModels.ProdInfoModel() - { - NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()), - NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()), - PreWarmCycle = S7.Net.Types.Int.FromByteArray(currMem.Skip(4).Take(2).ToArray()), - TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()), - TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()), - TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()), - TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()), - TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()), - MaterialTempEndWarm = S7.Net.Types.Double.FromByteArray(currMem.Skip(26).Take(4).ToArray()), - MaterialTempEndVent = S7.Net.Types.Double.FromByteArray(currMem.Skip(30).Take(4).ToArray()), - MoldTemp = S7.Net.Types.Double.FromByteArray(currMem.Skip(34).Take(4).ToArray()), - VacuumReadVal = S7.Net.Types.Double.FromByteArray(currMem.Skip(38).Take(4).ToArray()), - MouldEnergyOUT = S7.Net.Types.Double.FromByteArray(currMem.Skip(42).Take(4).ToArray()), - MouldEnergyIN = S7.Net.Types.Double.FromByteArray(currMem.Skip(46).Take(4).ToArray()), - NumPreHot = S7.Net.Types.Int.FromByteArray(currMem.Skip(50).Take(2).ToArray()) - }; - - // aggiorno... - currProdInfo.NumTarget = numTarget; - currProdInfo.PreWarmCycle = preWarmCycle; - // converto a byte... - List newMem = currProdInfo.convertToByte().ToList(); - // riscrivo!!!! - libraryError = MEM_RWByteList(W, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref newMem); - if (libraryError.IsError()) - return libraryError; - - if (doReset) - { - // send strobe of NEW WorkOrder / reset QTY - libraryError = PLC_WStrobe(true, PROD_ACK, PROD_STROBE, 10); - if (libraryError.IsError()) - return libraryError; - } - - return NO_ERROR; - } - /// - /// Get current Production Cycle data - /// - /// - /// - public override CmsError PLC_RProdCycle(ref ThermoModels.ProdCycleModel currProdCycle) - { - List currMem = new List(); - CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_CYCLE.MemType, PROCESS_PROD_CYCLE.Address, PROCESS_PROD_CYCLE.SubAddress, 0, PROCESS_PROD_CYCLE.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - // converto! - currProdCycle = new ThermoModels.ProdCycleModel() - { - Status = S7.Net.Types.Word.FromByteArray(currMem.Skip(0).Take(2).ToArray()), - MessageId = S7.Net.Types.Word.FromByteArray(currMem.Skip(2).Take(2).ToArray()), - Mode = S7.Net.Types.Byte.FromByteArray(currMem.Skip(4).Take(1).ToArray()), - Submode = S7.Net.Types.Byte.FromByteArray(currMem.Skip(5).Take(1).ToArray()), - TimeAdv = S7.Net.Types.DWord.FromByteArray(currMem.Skip(6).Take(4).ToArray()) - }; - - return NO_ERROR; - } - - - /// - /// Refresh recipE parameters RT - /// - protected CmsError refreshMemRecipeParameterRT() - { - CmsError libraryError = NO_ERROR; - 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 - { } - } - } - } - } - + CmsError libraryError = MEM_RWBoolean(W, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 0, ref enableTCam); return libraryError; } - /// - /// Refresh recipe parameters - /// - protected CmsError refreshMemRecipeParameter() - { - CmsError libraryError = NO_ERROR; - 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); + public override CmsError PLC_WTerminateAssistedToolingProcedure() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PLC_WTerminateMovementProcedure(MOVEMENT_RESPONSE resp) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PLC_WUserSoftKey(uint id) + { + // Check id range + if (id > USER_SOFTKEYS_NUMBER) + return INCORRECT_PARAMETERS_ERROR; + + // Write strobe into memory --> false because is bitArray + CmsError libraryError = PLC_WStrobe(false, USER_SOFT_KEYS_ACK, USER_SOFT_KEYS_CLICKED, id); 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; - } - - - return libraryError; - } - /// - /// Oggetto Parametro RT da PLC - /// - protected class PlcParamRT - { - public short Id { get; set; } = 0; - private byte Stato { get; set; } = 0; - public bool Visible { get; set; } - public bool Enabled { get; set; } - public bool HasError { get; set; } - public int ValueAct { get; set; } = 0; - /// - /// Deserializzazione da byte ad oggetto ParamRT - /// - /// - public PlcParamRT(byte[] rawData) - { - // converto i dati da byte grezzi ai 3 componenti... - Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); - ValueAct = S7.Net.Types.DInt.FromByteArray(rawData.Skip(4).Take(4).ToArray()); - Visible = S7.Net.Types.Boolean.GetValue(rawData[2], 0); - Enabled = S7.Net.Types.Boolean.GetValue(rawData[2], 1); - HasError = S7.Net.Types.Boolean.GetValue(rawData[2], 2); -#if false - // calcolo bit... - Stato = S7.Net.Types.Word.FromByteArray(rawData.Skip(2).Take(2).Reverse().ToArray()); - Visible = (Stato & 1) == 1; - Enabled = (Stato & 2) == 2; - HasError = (Stato & 4) == 4; -#endif - } - /// - /// Converte un singolo item in un array di byte per scrittura su PLC S7 - /// - /// - public byte[] convertToByte() - { - // convero stato dai bit... - Stato = 0; - Stato += (byte)(Visible ? 1 : 0); - Stato += (byte)(Enabled ? 2 : 0); - Stato += (byte)(HasError ? 4 : 0); - byte[] answ = new byte[8]; - Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); - Buffer.BlockCopy(S7.Net.Types.Byte.ToByteArray(Stato), 0, answ, 2, 1); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValueAct), 0, answ, 4, 4); - return answ; - } - } - /// - /// Oggetto Parametro da PLC - /// - protected class PlcParam - { - public short Id { get; set; } = 0; - public int SetpointHMI { get; set; } = 0; - public int SetpointPLC { get; set; } = 0; - public int ValMax { get; set; } = 0; - public int ValMin { get; set; } = 0; - public ushort UnitMeasure { get; set; } = 0; - /// - /// Deserializzazione da byte ad oggetto Param - /// - /// - public PlcParam(byte[] rawData) - { - // converto i dati da byte grezzi ai 3 componenti... - Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); - SetpointHMI = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray()); - SetpointPLC = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray()); - ValMax = S7.Net.Types.DInt.FromByteArray(rawData.Skip(10).Take(4).ToArray()); - ValMin = S7.Net.Types.DInt.FromByteArray(rawData.Skip(14).Take(4).ToArray()); - UnitMeasure = S7.Net.Types.Word.FromByteArray(rawData.Skip(18).Take(2).ToArray()); - } - /// - /// Converte un singolo item in un array di byte per scrittura su PLC S7 - /// - /// - public byte[] convertToByte() - { - byte[] answ = new byte[20]; - Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(SetpointHMI), 0, answ, 2, 4); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(SetpointPLC), 0, answ, 6, 4); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValMax), 0, answ, 10, 4); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValMin), 0, answ, 14, 4); - Buffer.BlockCopy(S7.Net.Types.Word.ToByteArray(UnitMeasure), 0, answ, 18, 2); - return answ; - } + return NO_ERROR; } - /// - /// Refresh ModuleBlock RT - /// - protected void refreshMemModBlockParameterRT() - { - List currMem = new List(); - int packSize = 12; - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, MODULE_RT_DATA.MemType, MODULE_RT_DATA.Address, MODULE_RT_DATA.SubAddress, 0, MODULE_RT_DATA.Size, ref currMem); - - // controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < MODULE_RT_DATA.Size / packSize; i++) - { - PlcModBlockRT currModBlock = new PlcModBlockRT(memArray.Skip(i * packSize).Take(packSize).ToArray()); - // solo se ID > 0... - if (currModBlock.Id > 0) - { - // update oggetto thermoParamList... - if (ThermoModuleList.ContainsKey(currModBlock.Id)) - { - try - { - ThermoModuleList[currModBlock.Id].Visible = currModBlock.Visible; - ThermoModuleList[currModBlock.Id].Running = currModBlock.Running; - ThermoModuleList[currModBlock.Id].HasError = currModBlock.HasError; - ThermoModuleList[currModBlock.Id].Terminated = currModBlock.Terminated; - ThermoModuleList[currModBlock.Id].ActualDuration = currModBlock.ActualDuration; - ThermoModuleList[currModBlock.Id].ActualDelay = currModBlock.ActualDelay; - } - catch - { } - } - else - { - try - { - ThermoModuleList.Add(currModBlock.Id, new ThermoModels.ModuleBlock() - { - Id = currModBlock.Id, - ActualDuration = currModBlock.ActualDuration, - ActualDelay = currModBlock.ActualDelay, - Visible = currModBlock.Visible, - Running = currModBlock.Running, - HasError = currModBlock.HasError, - Terminated = currModBlock.Terminated - }); - } - catch - { } - } - } - else - { - libraryError = S7_PLC_WRONG_DATA; - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } - } - /// - /// Refresh ModuleBlock - /// - protected void refreshMemModBlockParameter() - { - List currMem = new List(); - int packSize = 18; - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, MODULE_DATA.MemType, MODULE_DATA.Address, MODULE_DATA.SubAddress, 0, MODULE_DATA.Size, ref currMem); - - - // controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < MODULE_DATA.Size / packSize; i++) - { - PlcModBlock currModBlock = new PlcModBlock(memArray.Skip(i * packSize).Take(packSize).ToArray()); - // calcolo lista PrecId - List PrecId = new List(); - PrecId.Add(currModBlock.PrevId_01); - PrecId.Add(currModBlock.PrevId_02); - PrecId.Add(currModBlock.PrevId_03); - // solo se ID > 0... - if (currModBlock.Id > 0) - { - // update oggetto thermoParamList... - if (ThermoModuleList.ContainsKey(currModBlock.Id)) - { - ThermoModuleList[currModBlock.Id].EstimatedDelay = currModBlock.EstimDelay; - ThermoModuleList[currModBlock.Id].EstimatedDuration = currModBlock.EstimDuration; - ThermoModuleList[currModBlock.Id].PrecedingId = PrecId; - } - else - { - ThermoModuleList.Add(currModBlock.Id, new ThermoModels.ModuleBlock() - { - Id = currModBlock.Id, - EstimatedDelay = currModBlock.EstimDelay, - EstimatedDuration = currModBlock.EstimDuration, - PrecedingId = PrecId - }); - } - } - else - { - libraryError = S7_PLC_WRONG_DATA; - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } - } - /// - /// Oggetto Modulo Blocco RT da PLC - /// - protected class PlcModBlockRT - { - public short Id { get; set; } = 0; - public int ActualDuration { get; set; } = 0; - public int ActualDelay { get; set; } = 0; - private ushort Stato { get; set; } = 0; - public bool Visible { get; set; } - public bool Running { get; set; } - public bool HasError { get; set; } - public bool Terminated { get; set; } = false; - /// - /// Deserializzazione da byte ad oggetto ParamRT - /// - /// - public PlcModBlockRT(byte[] rawData) - { - // converto i dati da byte grezzi ai 3 componenti... - Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); - ActualDuration = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray()); - ActualDelay = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray()); - // sono in realtà BIT STRUC --> reverse! - Stato = S7.Net.Types.Word.FromByteArray(rawData.Skip(10).Take(2).Reverse().ToArray()); - // calcolo bit... - Visible = (Stato & 1) == 1; - Running = (Stato & 2) == 2; - HasError = (Stato & 4) == 4; - Terminated = (Stato & 8) == 8; - } - /// - /// Converte un singolo item in un array di byte per scrittura su PLC S7 - /// - /// - public byte[] convertToByte() - { - // convero stato dai bit... - Stato = 0; - Stato += (ushort)(Visible ? 1 : 0); - Stato += (ushort)(Running ? 2 : 0); - Stato += (ushort)(HasError ? 4 : 0); - Stato += (ushort)(Terminated ? 8 : 0); - byte[] answ = new byte[12]; - Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ActualDuration), 0, answ, 2, 4); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ActualDelay), 0, answ, 6, 4); - Buffer.BlockCopy(S7.Net.Types.Word.ToByteArray(Stato), 0, answ, 10, 1); - return answ; - } - } - /// - /// Oggetto Modulo Blocco da PLC - /// - protected class PlcModBlock - { - public short Id { get; set; } = 0; - public int EstimDuration { get; set; } = 0; - public int EstimDelay { get; set; } = 0; - public short PrevId_01 { get; set; } = 0; - public short PrevId_02 { get; set; } = 0; - public short PrevId_03 { get; set; } = 0; - /// - /// Deserializzazione da byte ad oggetto Param - /// - /// - public PlcModBlock(byte[] rawData) - { - // converto i dati da byte grezzi ai 3 componenti... - Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); - EstimDuration = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray()); - EstimDelay = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray()); - PrevId_01 = S7.Net.Types.Int.FromByteArray(rawData.Skip(12).Take(2).ToArray()); - PrevId_02 = S7.Net.Types.Int.FromByteArray(rawData.Skip(14).Take(2).ToArray()); - PrevId_03 = S7.Net.Types.Int.FromByteArray(rawData.Skip(16).Take(2).ToArray()); - } - /// - /// Converte un singolo item in un array di byte per scrittura su PLC S7 - /// - /// - public byte[] convertToByte() - { - byte[] answ = new byte[18]; - Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(EstimDuration), 0, answ, 2, 4); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(EstimDelay), 0, answ, 6, 4); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_01), 0, answ, 12, 2); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_02), 0, answ, 14, 2); - Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_03), 0, answ, 16, 2); - return answ; - } - } - - /// - /// Refresh dati ThermoCamera dal PLC: temperatura impostata come riferimento - /// - private void refreshRiscTermoCamTempSet() - { - // leggo DB624 x Setpoint Temp richiesti - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - for (int i = 0; i < TCAM_TEMP_REQ_DATA.Size / 2; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - try - { - ThermoWarmChannels[i + 1].TCamTempSet = currMem[i]; - } - catch - { } - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - TCamTempSet = currMem[i] - }); - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } - } - /// - /// Refresh dati ThermoCamera dal PLC: ultima temp letta - /// - private void refreshRiscTermoCamTempAct() - { - // leggo DB625 x Temp attuale - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_ACT_DATA.MemType, TCAM_TEMP_ACT_DATA.Address, TCAM_TEMP_ACT_DATA.SubAddress, TCAM_TEMP_ACT_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - for (int i = 0; i < TCAM_TEMP_ACT_DATA.Size / 2; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - try - { - ThermoWarmChannels[i + 1].TCamTempActual = currMem[i]; - } - catch - { } - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - TCamTempActual = currMem[i] - }); - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } - } - /// - /// Refresh dati ThermoCamera dal PLC x area command/status - /// - private void refreshRiscTermoCamCommStatus() - { -#if false - // leggo DB614 x area Ich - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < RISC_CHP_DATA.Size; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - try - { - ThermoWarmChannels[i + 1].SetpointHMI = memArray[i]; - } - catch - { } - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - SetpointHMI = memArray[i] - }); - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } -#endif - } - /// - /// Refresh dati ThermoCamera dal PLC x area command/status - /// - private void refreshRiscTermoCamEnab() - { - // leggo DB664 x abilitazione ch alla termocamera - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - bool[] bits = new bool[TCAM_CH_ENAB_DATA.Size * 8]; - - // Convert int into to true/false array - var bArray = new BitArray(currMem.ToArray()); - bArray.CopyTo(bits, 0); - - for (int i = 0; i < TCAM_CH_ENAB_DATA.Size * 8; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - try - { - ThermoWarmChannels[i + 1].TCamActive = bits[i]; - } - catch - { } - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - TCamActive = bits[i] - }); - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } - } - /// - /// Refresh Canali Riscaldi: SetPoint HMI - /// - private void refreshRiscSetpointHMI() - { - // leggo DB614 x area Ich - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < RISC_CHP_DATA.Size; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - try - { - ThermoWarmChannels[i + 1].SetpointHMI = memArray[i]; - } - catch - { } - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - SetpointHMI = memArray[i] - }); - } - } - } - else - { - libraryError = S7_PLC_EMPTY_READ; - } - } - /// - /// Refresh Canali Riscaldi: SetPoint PLC (% lavoro applicata ATTUALE dal PLC) - /// - private void refreshRiscSetpointPLC() - { - // leggo area DB627 (era DB514) x area CHp - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_PLC_DATA.MemType, RISC_PLC_DATA.Address, RISC_PLC_DATA.SubAddress, 0, RISC_PLC_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < RISC_PLC_DATA.Size; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - ThermoWarmChannels[i + 1].SetpointPLC = memArray[i]; - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - SetpointPLC = memArray[i] - }); - } - } - } - } - /// - /// Refresh Canali Riscaldi: actual current PLC - /// - private void refreshRiscActCurr() - { - // leggo DB514 x area Ich - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_ICH_DATA.MemType, RISC_ICH_DATA.Address, RISC_ICH_DATA.SubAddress, 0, RISC_ICH_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - double currVal = 0; - for (int i = 0; i < RISC_ICH_DATA.Size / 4; i++) - { - currVal = S7.Net.Types.Double.FromByteArray(memArray.Skip(4 * i).Take(4).ToArray()); - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - ThermoWarmChannels[i + 1].CurrAct = currVal; - } - else - { - try - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - CurrAct = currVal - }); - } - catch - { } - } - } - } - } - /// - /// Refresh Canali Riscaldi: Percentuale lavoro Attuale - /// - private void refreshRiscPerc() - { - // leggo DB514 x area OVp - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_OVP_DATA.MemType, RISC_OVP_DATA.Address, RISC_OVP_DATA.SubAddress, 0, RISC_OVP_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < RISC_OVP_DATA.Size; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - ThermoWarmChannels[i + 1].PercAct = memArray[i]; - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - PercAct = memArray[i] - }); - } - } - } - } - /// - /// Refresh Canali Riscaldi: Status - /// - private void refreshRiscStatus() - { - // leggo DB514 x area ESP - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_ESP_DATA.MemType, RISC_ESP_DATA.Address, RISC_ESP_DATA.SubAddress, 0, RISC_ESP_DATA.Size, ref currMem); - - // copio! controllo SE ho dati... - if (currMem.Count > 0) - { - // converto a blocchi di 8 byte... - byte[] memArray = currMem.ToArray(); - for (int i = 0; i < RISC_ESP_DATA.Size; i++) - { - // cerco id + 1 (su memoria è base 0) - if (ThermoWarmChannels.ContainsKey(i + 1)) - { - ThermoWarmChannels[i + 1].ChStatus = memArray[i]; - } - else - { - ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel() - { - IdChannel = i + 1, - ChStatus = memArray[i] - }); - } - } - } - } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Write Warmers channels load data @@ -3423,44 +4911,43 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } + /// - /// Set current Warmers Channels Temp REF Setpoints (1/10 °C) + /// Set current Warmers Channels as enabled/disabled for working with thermo camera data /// - /// + /// /// - public override CmsError PLC_WWarmerChTCamTempSet(Dictionary newData) + public override CmsError PLC_WWarmerChTCamEnab(Dictionary newData) { - // valori in 1/10 di °C - int dataScale = 10; - // memory area - short[] newMem = new short[newData.Count]; - // leggo DB624 x Setpoint Temp richiesti - List currMem = new List(); - - // leggo da PLC a array di byte di appoggio... - CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem); + // leggo DB664 x abilitazione ch alla termocamera + bool[] newMem = new bool[TCAM_CH_ENAB_DATA.Size * 8]; + List currMem = new List(); + // read actual data on memory... + CmsError libraryError = MEM_RWByteList(R, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem); if (libraryError.IsError()) return libraryError; - newMem = currMem.ToArray(); + // Convert int into to true/false array + BitArray bArray = new BitArray(currMem.ToArray()); + bArray.CopyTo(newMem, 0); // update only given data... foreach (var item in newData) { - // attenzione: effettua scalatura dati! - newMem[item.Key - 1] = (short)(dataScale * item.Value); + newMem[item.Key - 1] = item.Value; } // return as list... - currMem = newMem.ToList(); + currMem = boolsToByteArray(newMem).ToList(); // scrivo sul PLC array di byte... - libraryError = MEM_RWShortList(W, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem); + libraryError = MEM_RWByteList(W, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem); if (libraryError.IsError()) return libraryError; - return NO_ERROR; + return libraryError; } + /// /// Set current Warmers Channels Thermocam read (actual) value (°C) /// @@ -3500,90 +4987,109 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } - /// - /// Set current Warmers Channels as enabled/disabled for working with thermo camera data + /// Set current Warmers Channels Temp REF Setpoints (1/10 °C) /// - /// + /// /// - public override CmsError PLC_WWarmerChTCamEnab(Dictionary newData) + public override CmsError PLC_WWarmerChTCamTempSet(Dictionary newData) { - // leggo DB664 x abilitazione ch alla termocamera - bool[] newMem = new bool[TCAM_CH_ENAB_DATA.Size * 8]; - List currMem = new List(); + // valori in 1/10 di °C + int dataScale = 10; + // memory area + short[] newMem = new short[newData.Count]; + // leggo DB624 x Setpoint Temp richiesti + List currMem = new List(); + + // leggo da PLC a array di byte di appoggio... + CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem); - // read actual data on memory... - CmsError libraryError = MEM_RWByteList(R, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem); if (libraryError.IsError()) return libraryError; - - // Convert int into to true/false array - BitArray bArray = new BitArray(currMem.ToArray()); - bArray.CopyTo(newMem, 0); + newMem = currMem.ToArray(); // update only given data... foreach (var item in newData) { - newMem[item.Key - 1] = item.Value; + // attenzione: effettua scalatura dati! + newMem[item.Key - 1] = (short)(dataScale * item.Value); } // return as list... - currMem = boolsToByteArray(newMem).ToList(); + currMem = newMem.ToList(); // scrivo sul PLC array di byte... - libraryError = MEM_RWByteList(W, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem); + libraryError = MEM_RWShortList(W, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem); if (libraryError.IsError()) return libraryError; - return libraryError; + return NO_ERROR; } - public static byte[] boolsToByteArray(bool[] bits) + /// + /// Set current Warmers Channels reflector's data + /// + /// + /// + public override CmsError PLC_WWarmerConfBoardEnabl(Dictionary newData) { - // pack (in this case, using the first bool as the lsb - if you want - // the first bool as the msb, reverse things ;-p) - int bytes = bits.Length / 8; - if ((bits.Length % 8) != 0) bytes++; - byte[] answ = new byte[bytes]; - int bitIndex = 0, byteIndex = 0; - for (int i = 0; i < bits.Length; i++) + // memory area + byte[] newMem = new byte[newData.Count]; + List currMem = new List(); + + // read actual data on memory... + CmsError libraryError = MEM_RWByteList(R, 0, RISC_OCC_DATA.MemType, RISC_OCC_DATA.Address, RISC_OCC_DATA.SubAddress, 0, RISC_OCC_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; + + newMem = currMem.ToArray(); + + // update only given data... + foreach (var item in newData) { - if (bits[i]) - { - answ[byteIndex] |= (byte)(((byte)1) << bitIndex); - } - bitIndex++; - if (bitIndex == 8) - { - bitIndex = 0; - byteIndex++; - } + newMem[item.Key] = (byte)item.Value; } + // return as list... + currMem = newMem.ToList(); + // scrivo sul PLC array di byte... + libraryError = MEM_RWByteList(W, 0, RISC_OCC_DATA.MemType, RISC_OCC_DATA.Address, RISC_OCC_DATA.SubAddress, 0, RISC_OCC_DATA.Size, ref currMem); + if (libraryError.IsError()) + return libraryError; - return answ; - } - - - /// - /// Set ThermoCamera mode - /// - /// - /// - public override CmsError PLC_WTCamMode(bool enableTCam) - { - CmsError libraryError = MEM_RWBoolean(W, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 0, ref enableTCam); - return libraryError; + return NO_ERROR; } /// - /// Set ThermoCamera functionality active (HMI) + /// Set current Warmers Channels min current data /// - /// + /// /// - public override CmsError PLC_WTCamActiv(bool enableTCam) + public override CmsError PLC_WWarmerConfMinCurr(Dictionary newData) { - CmsError libraryError = MEM_RWBoolean(W, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 1, ref enableTCam); - return libraryError; + // memory area + List ListValue = new List(); + + // read actual data on memory... + CmsError libraryError = MEM_RWDoubleList(R, 0, RISC_ICH_MIN_DATA.MemType, RISC_ICH_MIN_DATA.Address, RISC_ICH_MIN_DATA.SubAddress, RISC_ICH_MIN_DATA.Size, ref ListValue); + if (libraryError.IsError()) + return libraryError; + + var newMem = ListValue.ToArray(); + + // update only given data... + foreach (var item in newData) + { + // 2020.07.21 fix perché channes 1 based, memory 0 based + newMem[item.Key - 1] = item.Value; + } + // return as list... + ListValue = newMem.ToList(); + // scrivo sul PLC array di byte... + libraryError = MEM_RWDoubleList(W, 0, RISC_ICH_MIN_DATA.MemType, RISC_ICH_MIN_DATA.Address, RISC_ICH_MIN_DATA.SubAddress, RISC_ICH_MIN_DATA.Size, ref ListValue); + if (libraryError.IsError()) + return libraryError; + + return NO_ERROR; } /// @@ -3619,1304 +5125,437 @@ namespace CMS_CORE_Library.S7Net return NO_ERROR; } - /// - /// Get current Warmers VUMin data - /// - /// - /// - public override CmsError PLC_RWarmerConfVUMin(ref ushort VUmin) + + // Get the process Active Alarms + public override CmsError PROC_RActiveAlarms(ushort procNumber, ref List alarms) { - // leggo da 513.0 --> default 210 - VUmin = 230; - List currMem = new List(); - - // read actual data on memory... - CmsError libraryError = MEM_RWWord(R, 0, RISC_VU_MIN.MemType, RISC_VU_MIN.Address, RISC_VU_MIN.SubAddress, ref VUmin); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - /// - /// Set current Warmers Channels min current data - /// - /// - /// - public override CmsError PLC_WWarmerConfMinCurr(Dictionary newData) - { - // memory area - List ListValue = new List(); - - // read actual data on memory... - CmsError libraryError = MEM_RWDoubleList(R, 0, RISC_ICH_MIN_DATA.MemType, RISC_ICH_MIN_DATA.Address, RISC_ICH_MIN_DATA.SubAddress, RISC_ICH_MIN_DATA.Size, ref ListValue); - if (libraryError.IsError()) - return libraryError; - - var newMem = ListValue.ToArray(); - - // update only given data... - foreach (var item in newData) - { - // 2020.07.21 fix perché channes 1 based, memory 0 based - newMem[item.Key - 1] = item.Value; - } - // return as list... - ListValue = newMem.ToList(); - // scrivo sul PLC array di byte... - libraryError = MEM_RWDoubleList(W, 0, RISC_ICH_MIN_DATA.MemType, RISC_ICH_MIN_DATA.Address, RISC_ICH_MIN_DATA.SubAddress, RISC_ICH_MIN_DATA.Size, ref ListValue); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - /// - /// Set current Warmers Channels reflector's data - /// - /// - /// - public override CmsError PLC_WWarmerConfBoardEnabl(Dictionary newData) - { - // memory area - byte[] newMem = new byte[newData.Count]; - List currMem = new List(); - - // read actual data on memory... - CmsError libraryError = MEM_RWByteList(R, 0, RISC_OCC_DATA.MemType, RISC_OCC_DATA.Address, RISC_OCC_DATA.SubAddress, 0, RISC_OCC_DATA.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - newMem = currMem.ToArray(); - - // update only given data... - foreach (var item in newData) - { - newMem[item.Key] = (byte)item.Value; - } - // return as list... - currMem = newMem.ToList(); - // scrivo sul PLC array di byte... - libraryError = MEM_RWByteList(W, 0, RISC_OCC_DATA.MemType, RISC_OCC_DATA.Address, RISC_OCC_DATA.SubAddress, 0, RISC_OCC_DATA.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - return NO_ERROR; - } - /// - /// Request for mode selection via strobe - /// - /// 1: MAN, 2: AUTO, 3: SETUP - /// - public override CmsError PLC_WModeSel(int mode) - { - // se update --> scrivo strobe comando update... - if (mode == 1) - { - // Call confirm update - CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 6); - if (libraryError.IsError()) - return libraryError; - } - else - if (mode == 2) - { - // Call confirm update - CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 5); - if (libraryError.IsError()) - return libraryError; - } - else - if (mode == 3) - { - // Call confirm update - CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 7); - if (libraryError.IsError()) - return libraryError; - } - - 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; + // FIXME TODO - fare guardando bitmap allarmi attivi #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) + alarms = SiemensAlarms + .Where(x => x.Id >= IDMinChannel && x.Id <= IDMaxChannel && x.Parameters[0].Equals(procNumber.ToString())) + .Select(x => { - // update oggetto thermoParamList... - if (ThermoParamList.ContainsKey(currParam.Id)) + uint id = x.Instance == 1 ? (uint)x.Id : Convert.ToUInt32((x.Id & 0xffff) | (x.Instance << 24)); + return new AlarmModel() { - 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 - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - #region PROCESS-AXES (PATH) High-level data - - - /// - /// Get current Production Info data - /// - /// - /// - public override CmsError PLC_RAxesMov(ref ThermoModels.AxisRT currProdInfo) - { - List currMem = new List(); - CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - -#if false - // converto! - currProdInfo = new ThermoModels.ProdInfoModel() - { - NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()), - NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()), - // cicli preriscaldo? FIXME TODO - TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()), - TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()), - TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()), - TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()), - TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()), - MaterialTempEndWarm = S7.Net.Types.Double.FromByteArray(currMem.Skip(26).Take(4).ToArray()), - MaterialTempEndVent = S7.Net.Types.Double.FromByteArray(currMem.Skip(30).Take(4).ToArray()), - MoldTemp = S7.Net.Types.Double.FromByteArray(currMem.Skip(34).Take(4).ToArray()), - VacuumReadVal = S7.Net.Types.Double.FromByteArray(currMem.Skip(38).Take(4).ToArray()), - MouldEnergyOUT = S7.Net.Types.Double.FromByteArray(currMem.Skip(42).Take(4).ToArray()), - MouldEnergyIN = S7.Net.Types.Double.FromByteArray(currMem.Skip(46).Take(4).ToArray()) - }; + Id = id, + Message = x.Message, + IsWarning = false, + Process = procNumber, + DateTime = x.TimeStamp + }; + }) + .ToList(); #endif return NO_ERROR; } - public override CmsError AXES_RInterpPosition(ushort channel, ref Dictionary axes) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_RMachinePosition(ushort channel, ref Dictionary axes) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_RProgrPosition(ushort channel, ref Dictionary axes) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_RFollowingError(ushort channel, ref Dictionary axes) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_RDistanceToGo(ushort channel, ref Dictionary axes) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - private Dictionary AXES_RAxesPos(ushort channel, string positionType) - { - Dictionary axes = new Dictionary(); - return axes; - } - - public override CmsError AXES_RAxesNames(ushort channel, ref List axesData) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_RSelectedAxis(ref byte axisId) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_WSelectAxis(byte axisId) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError AXES_ROrigin(int numberOfAxes) - { - return FUNCTION_NOT_ALLOWED_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, bool fixEndian, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemBit, ref bool Value) + // Get the process Mode + public override CmsError PROC_RMode(ushort ProcNumber, ref PROC_MODE Mode) { //Check if the NC is Connected CmsError libraryError = CheckConnection(); if (libraryError.IsError()) return libraryError; - //Check if the Bit Number is Correct - libraryError = CheckBitRange(MemBit); - if (libraryError.IsError()) - return libraryError; + // FIXME TODO - fare guardando mappatura memoria stsato processo - byte bValue = 0; - ushort pow = (ushort)Math.Pow(2, MemBit); - - //Read the Byte where is the bit - libraryError = MEM_RWByte(R, fixEndian, Process, MemType, MemTable, MemIndex, 0, ref bValue); - if (libraryError.IsError()) - return libraryError; - - //If i have to Write -> Write the Bit - if (bWrite) +#if false + // Try to get information + try { - if (Value) - bValue = (byte)(bValue | (1 << MemBit)); + // 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); + } +#endif + + return NO_ERROR; + } + + // Get PP Lines + public override CmsError PROC_RPPLines(ushort ProcNumber, ref List Lines) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + // Get PP Name + public override CmsError PROC_RSelectedPPName(ushort ProcNumber, ref string Name) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError PROC_RSelectedProcess(ref ushort procNumber) + { + if (SelectedProcess == 0) + return SELECTED_PROCESS_ERROR; + + procNumber = SelectedProcess; + //CmsError libraryError; + //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 + // libraryError = MEM_RWBoolean(R, 0, SELECTED_PROCESS.MemType, SELECTED_PROCESS.Address, memoryAddress, 2, ref readValue); + // if (libraryError.IsError()) + // return libraryError; + + // if (readValue) + // { + // procNumber = (ushort)(i + 1); + // return NO_ERROR; + // } + //} + + return NO_ERROR; + } + + public override CmsError PROC_RSelectedProcessData(int processId, ref SelectedProcessData processData) + { + if (processId <= 0) + return PROC_NOT_FOUND_ERROR; + + // FIXME TODO - ha senso? +#if false + 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); + } +#endif + + 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 libraryError = CheckConnection(); + if (libraryError.IsError()) + return libraryError; + + // FIXME TODO - fare guardando mappatura variabili status +#if false + // 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); + } +#endif + + return NO_ERROR; + } + + // Get process part program data + public override CmsError PROC_RStatusAndData(ushort procNumber, ref ProcessDataModel processData) + { + processData.Id = procNumber; + CmsError libraryError = NO_ERROR; +#if false + // Read part program name + libraryError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName); + if (libraryError.IsError()) + return libraryError; +#endif + + // FIXME TODO --> forzato tutto a true... eventualmente rivedere in futuro x processo caricatore vs processo principale + bool forceValues = true; + + if (forceValues) + { + processData.Visible = true; + processData.Type = "WORK"; + processData.IsSelected = true; + processData.IsInAlarm = false; + processData.CanLoadProgram = true; + processData.Status = "RUN"; + processData.Reps = 0; + } + else + { + int readValue = 0; + + // Read processes status from memory + libraryError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address, PROCESS_STATUS.SubAddress + ((procNumber - 1) * 2), ref readValue); + if (libraryError.IsError()) + return libraryError; + + 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 - bValue = (byte)(bValue & ~(1 << MemBit)); + { + if (bytes[1] == 2) + processData.Status = "RUN"; + else + processData.Status = "READY"; + } - libraryError = MEM_RWByte(W, fixEndian, Process, MemType, MemTable, MemIndex, 0, ref bValue); - if (libraryError.IsError()) - return libraryError; - } - //If i have to read -> Read the Bit - else - { - Value = (bValue & pow) == pow; + // Get Reps from 3nd-4th byte + processData.Reps = BitConverter.ToUInt16(bytes, 2); } return NO_ERROR; } - /// - /// Read-Write a SINGLE Byte inside the NC. In writing-mode the field "Number" is not required - /// - /// R/W mode - /// fix endianness - /// - /// - /// - /// - /// - /// - /// - public override CmsError MEM_RWByte(bool bWrite, bool fixEndian, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByte, ref byte Value) + public override CmsError PROC_WSelectProcess(ushort procNumber) { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; + CmsError libraryError; + byte processNum = (byte)procNumber; - if (MemType != MEMORY_TYPE.Siemens_DB) - { + // Check parameter + if (processNum > MAX_PROCESS_NUMBER) return INCORRECT_PARAMETERS_ERROR; - } - libraryError = null; - - // attenzione endianness! inverte byte se richiesto... - int fixIndex = MemIndex; - if (fixEndian) - { - fixIndex = MemIndex % 2 == 0 ? MemIndex + 1 : MemIndex - 1; - } - - // vere operazioni R/W - if (bWrite) - { - // try/catch - try - { - byte[] DB_Byte = new byte[1]; - DB_Byte[0] = Value; - currPLC.WriteBytes(DataType.DataBlock, MemTable, fixIndex, DB_Byte); - } - catch - { - return S7_PLC_WRITE_ERROR_BYTE; - } - } - else - { - try - { - var memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, fixIndex, 1); - Value = memByteRead[0]; - } - catch - { - return S7_PLC_READ_ERROR_BYTE; - } - } - - 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 libraryError = MEM_RWWordList(bWrite, Process, MemType, MemTable, MemIndex, 2, ref ListValue); - if (libraryError.IsError()) - return libraryError; - if (ListValue.Count > 0) - 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 libraryError = MEM_RWShortList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue); + // Write process number + libraryError = MEM_RWByte(W, true, 0, SELECT_PROCESS.MemType, SELECT_PROCESS.Address, SELECT_PROCESS.SubAddress, 0, ref processNum); if (libraryError.IsError()) return libraryError; - 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 libraryError = MEM_RWDWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue); - if (libraryError.IsError()) - return libraryError; - - 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) - { - List ListValue = new List() { Value }; - - //uses the List method with one-element list - CmsError libraryError = MEM_RWDoubleList(bWrite, Process, MemType, MemTable, MemIndex, 4, ref ListValue); - if (libraryError.IsError()) - return libraryError; - - Value = ListValue.First(); - - 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, reading int32 (4byte) data... - CmsError libraryError = MEM_RWIntegerList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue); - if (libraryError.IsError()) - return libraryError; - if (ListValue.Count > 0) - { - Value = ListValue.First(); - } - - return NO_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 Values) - { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - if (MemType != MEMORY_TYPE.Siemens_DB) - { - return INCORRECT_PARAMETERS_ERROR; - } - - libraryError = null; - - if (bWrite) - { - //Prevent some exceptions - if (Values.Count == 0) - return NO_ERROR; - // try/catch - try - { - currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, Values.ToArray()); - } - catch - { - return S7_PLC_WRITE_ERROR_LST_BYTE; - } - } - else - { - // Prevent some exceptions - if (Number == 0) - return NO_ERROR; - Values.Clear(); - try - { - byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); - Values = memByteRead.ToList(); - } - catch - { - return S7_PLC_READ_ERROR_LST_BYTE; - } - } - - return NO_ERROR; - } - - public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) - { - ////Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - - if (MemType != MEMORY_TYPE.Siemens_DB) - { - return INCORRECT_PARAMETERS_ERROR; - } - - - libraryError = null; - - if (bWrite) - { - //Prevent some exceptions - if (Values.Count == 0) - return NO_ERROR; - - byte[] singleItem = new byte[2]; - List memByteList = new List(); - - foreach (var Item in Values) - { - singleItem = S7.Net.Types.Word.ToByteArray(Item); - memByteList.AddRange(singleItem); - } - try - { - currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); - } - catch - { - return S7_PLC_WRITE_ERROR_LST_WORD; - } - } - else - { - // Prevent some exceptions - if (Number == 0) - return NO_ERROR; - - Values.Clear(); - byte[] memByteRead; - try - { - memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); - // converto a word! - ushort shortVal = 0; - for (int i = 0; i < memByteRead.Length / 2; i++) - { - shortVal = S7.Net.Types.Word.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray()); - Values.Add(shortVal); - } - } - catch - { - return S7_PLC_READ_ERROR_LST_WORD; - } - } - - return NO_ERROR; - } - - public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) - { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - if (MemType != MEMORY_TYPE.Siemens_DB) - { - return INCORRECT_PARAMETERS_ERROR; - } - - - libraryError = null; - - if (bWrite) - { - //Prevent some exceptions - if (Values.Count == 0) - return NO_ERROR; - - byte[] singleItem = new byte[2]; - List memByteList = new List(); - - foreach (var Item in Values) - { - singleItem = S7.Net.Types.Int.ToByteArray(Item); - memByteList.AddRange(singleItem); - } - try - { - currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); - } - catch - { - return S7_PLC_WRITE_ERROR_LST_SHORT; - } - } - else - { - // Prevent some exceptions - if (Number == 0) - return NO_ERROR; - - Values.Clear(); - try - { - byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); - // converto a word! - short shortVal = 0; - for (int i = 0; i < memByteRead.Length / 2; i++) - { - shortVal = S7.Net.Types.Int.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray()); - Values.Add(shortVal); - } - } - catch - { - return S7_PLC_READ_ERROR_LST_SHORT; - } - } - - return NO_ERROR; - } - - public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) - { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - if (MemType != MEMORY_TYPE.Siemens_DB) - { - return INCORRECT_PARAMETERS_ERROR; - } - - libraryError = null; - - if (bWrite) - { - //Prevent some exceptions - if (Values.Count == 0) - return NO_ERROR; - - byte[] singleItem = new byte[4]; - List memByteList = new List(); - - foreach (var Item in Values) - { - singleItem = S7.Net.Types.DWord.ToByteArray(Item); - memByteList.AddRange(singleItem); - } - - try - { - currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); - } - catch - { - return S7_PLC_WRITE_ERROR_LST_DWORD; - } - } - else - { - // Prevent some exceptions - if (Number == 0) - return NO_ERROR; - - Values.Clear(); - - try - { - byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); - // converto a word! - uint shortVal = 0; - for (int i = 0; i < memByteRead.Length / 4; i++) - { - shortVal = S7.Net.Types.DWord.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); - Values.Add(shortVal); - } - } - catch - { - return S7_PLC_READ_ERROR_LST_DWORD; - } - } - - return NO_ERROR; - } - - - /// - /// Lettura lista di interi - /// - /// - /// - /// - /// - /// - /// numero di INT 32 da leggere (byte/4) - /// - /// - public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) - { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - if (MemType != MEMORY_TYPE.Siemens_DB) - { - return INCORRECT_PARAMETERS_ERROR; - } - - libraryError = null; - - if (bWrite) - { - //Prevent some exceptions - if (Values.Count == 0) - return NO_ERROR; - - byte[] singleItem = new byte[4]; - List memByteList = new List(); - - foreach (var Item in Values) - { - singleItem = S7.Net.Types.DInt.ToByteArray(Item); - memByteList.AddRange(singleItem); - } - try - { - currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); - } - catch - { - return S7_PLC_WRITE_ERROR_LST_INT; - } - } - else - { - // Prevent some exceptions - if (Number == 0) - return NO_ERROR; - - Values.Clear(); - byte[] memByteRead = null; - try - { - memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number * 4); - // converto a word! - int intVal = 0; - for (int i = 0; i < memByteRead.Length / 4; i++) - { - intVal = S7.Net.Types.DInt.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); - Values.Add(intVal); - } - } - catch - { - return S7_PLC_READ_ERROR_LST_INT; - } - } - - if (Values.Count == 0) - { - return NOT_CONNECTED_ERROR; - } - - return NO_ERROR; - } - - public override CmsError MEM_RWDoubleList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List Values) - { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - if (MemType != MEMORY_TYPE.Siemens_DB) - { - return INCORRECT_PARAMETERS_ERROR; - } - - libraryError = null; - - if (bWrite) - { - //Prevent some exceptions - if (Values.Count == 0) - return NO_ERROR; - - byte[] singleItem = new byte[4]; - List memByteList = new List(); - - foreach (var Item in Values) - { - singleItem = S7.Net.Types.Double.ToByteArray(Item); - memByteList.AddRange(singleItem); - } - - try - { - currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray()); - } - catch - { - return S7_PLC_WRITE_ERROR_LST_DOUBLE; - } - } - else - { - // Prevent some exceptions - if (Number == 0) - return NO_ERROR; - - Values.Clear(); - - try - { - byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number); - // converto a word! - double shortVal = 0; - for (int i = 0; i < memByteRead.Length / 4; i++) - { - shortVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray()); - Values.Add(shortVal); - } - } - catch - { - return S7_PLC_READ_ERROR_LST_DOUBLE; - } - } - - 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) + public override CmsError TOOLS_RAdatpivePathStep(ref Byte step) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError NC_RParam(short Index, ref byte Value) + public override CmsError TOOLS_RAvailableTools(ref List multiTools, ref List tools) { 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 - - /// - /// Get list of recipe (from local PC area) - /// - /// - /// - /// - public CmsError FILES_RecipeList(string path, ref List file) - { - return NO_ERROR; - - } - - /// - /// Load selected recipe, convert and save to PLC memory area - /// - /// - /// - /// - public CmsError FILES_LoadRecipe(string path, string name) - { - return NO_ERROR; - } - /// - /// Save current recipe from PLC memory area to file - /// - /// - /// - /// - public CmsError FILES_SaveRecipe(string path, string name) - { - return NO_ERROR; - } - - public override CmsError FILES_RGetFileList(string path, ref List files) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_RGetFileInfo(string path, ref InfoFile fileInfo) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WSetActiveProgram(int processId, string filePath, ref ActiveProgramDataModel data) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WDeactivateProgram(int processId) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_RActiveProgramData(int processId, ref ActiveProgramDataModel programData) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_UploadPartProgram(string localPath, string name, ref string newFilePath) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_CopyProgram(string partProgramPath, string newPartProgramPath, bool failIfExist) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_DeleteProgram(string partProgramPath, string partProgramName) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_RProgramToFile(string partProgramPath, FileStream localFile) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WProgramFromFile(string partProgramPath, FileStream localFile) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_RQueueData(ref List statusList) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_RQueueDataByProcess(ref QueueStatusModel status, int processId) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WStartQueue() - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WStopQueue() - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WLoadNextPartProgram(string localPath, string ncFileName) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError FILES_WUploadJobFilesAndActivate(int processId, string jobExtractedPath, string fileToActivate) - { - return FUNCTION_NOT_ALLOWED_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) - { - return FUNCTION_NOT_ALLOWED_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 Tools Management - public override CmsError TOOLS_RConfiguration(ref ToolTableConfiguration config) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RToolsData(ref List toolTable) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_RShanksData(ref List shanksData) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - public override CmsError TOOLS_RFamilyData(ref List families) { return FUNCTION_NOT_ALLOWED_ERROR; } + public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_RMagazineBlock(ref List ids) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_RMagazineConfig(ref List config) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + public override CmsError TOOLS_RMagazinePositions(ref List positions) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WAddTool(ref SiemensToolModel tool) + public override CmsError TOOLS_RMagazineStatus(ref Dictionary magazineStatus) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_RMountedTools(int magazineId, ref List magazinePos) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_ROffset(short offsetId, ref OffsetModel offset) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_RShanksData(ref List shanksData) + { + 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_RToolsData(ref List toolTable) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_RUpdatedToolsData(ref Dictionary updatedStatus, ref Dictionary updatedLives, ref Dictionary updatedPresetting, ref Dictionary updatedDressing) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WAbortBallufTablet() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WAdatpivePathStep(Byte step) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WAddEdge(int toolId, ref EdgeModel edge) { return FUNCTION_NOT_ALLOWED_ERROR; } @@ -4931,32 +5570,7 @@ namespace CMS_CORE_Library.S7Net return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WUpdateFamilyData(string oldName, string newName) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_WUpdatePosition(PositionModel position) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_WUpdateTool(ref SiemensToolModel tool) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_WDeleteTool(int id) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_WDeleteShank(int id) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_WDeleteFamily(string name) + public override CmsError TOOLS_WAddTool(ref SiemensToolModel tool) { return FUNCTION_NOT_ALLOWED_ERROR; } @@ -4966,27 +5580,32 @@ namespace CMS_CORE_Library.S7Net return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WAddEdge(int toolId, ref EdgeModel edge) + public override CmsError TOOLS_WDeleteFamily(string name) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WUpdateEdge(int toolId, ref EdgeModel newEdge) + public override CmsError TOOLS_WDeleteShank(int id) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WUpdateShank(ref ShankModel shank) + public override CmsError TOOLS_WDeleteTool(int id) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RMountedTools(int magazineId, ref List magazinePos) + public override CmsError TOOLS_WEmptyBallufTablet(SiemensToolModel tool) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RAvailableTools(ref List multiTools, ref List tools) + public override CmsError TOOLS_WEmptyBallufTabletAdditionalData(SiemensToolModel tool) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WFreeMagazines() { return FUNCTION_NOT_ALLOWED_ERROR; } @@ -4996,22 +5615,33 @@ namespace CMS_CORE_Library.S7Net return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WUnloadToolFromMagazine(int magazineId, int positionId) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - public override CmsError TOOLS_WLoadToolIntoShank(int shankId, int positionId, int toolId) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WUnloadToolFromShank(int shankId, int positionId) + public override CmsError TOOLS_WOffset(short offsetId, ref OffsetModel offset) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction) + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public override CmsError TOOLS_WOptions(ToolManagerOptionsModel options) + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WRestoreBackup() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WStartEditData() + { + return FUNCTION_NOT_ALLOWED_ERROR; + } + + public override CmsError TOOLS_WStartEditTooling(int magazineId) { return FUNCTION_NOT_ALLOWED_ERROR; } @@ -5026,494 +5656,328 @@ namespace CMS_CORE_Library.S7Net return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WEmptyBallufTablet(SiemensToolModel tool) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - public override CmsError TOOLS_WEmptyBallufTabletAdditionalData(SiemensToolModel tool) - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - public override CmsError TOOLS_WAbortBallufTablet() - { - return FUNCTION_NOT_ALLOWED_ERROR; - } - - #endregion Siemens Tools 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() + public override CmsError TOOLS_WUnloadToolFromMagazine(int magazineId, int positionId) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RUpdatedToolsData(ref Dictionary updatedStatus, ref Dictionary updatedLives, ref Dictionary updatedPresetting, ref Dictionary updatedDressing) + public override CmsError TOOLS_WUnloadToolFromShank(int shankId, int positionId) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RStoredData(ref List tools, ref List families, ref List shanks) + public override CmsError TOOLS_WUpdateEdge(int toolId, ref EdgeModel newEdge) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RMagazineBlock(ref List ids) + public override CmsError TOOLS_WUpdateFamilies(List list) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WFreeMagazines() + public override CmsError TOOLS_WUpdateFamilyData(string oldName, string newName) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RMagazineStatus(ref Dictionary magazineStatus) + public override CmsError TOOLS_WUpdateMagazinePositions(List list) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_RAdatpivePathStep(ref Byte step) + public override CmsError TOOLS_WUpdatePosition(PositionModel position) { return FUNCTION_NOT_ALLOWED_ERROR; } - public override CmsError TOOLS_WAdatpivePathStep(Byte step) + public override CmsError TOOLS_WUpdateShank(ref ShankModel shank) { return FUNCTION_NOT_ALLOWED_ERROR; } - #endregion Nc Tool Manager - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - #region Subordinate Private Functions - - private void NcLanguageChanged(string language) + public override CmsError TOOLS_WUpdateShanks(List list) { + return FUNCTION_NOT_ALLOWED_ERROR; } - private int SetBitValue(int intVal, bool val, int bitIndex) + public override CmsError TOOLS_WUpdateTool(ref SiemensToolModel tool) { - if (val) - return intVal | (1 << (bitIndex - 1)); - else - return intVal & ~(1 << (bitIndex - 1)); + return FUNCTION_NOT_ALLOWED_ERROR; } - //Manage the Mode - private PROC_MODE ConvertToSTEPMode(uint mode, uint JogMode, uint AdvMode) + public override CmsError TOOLS_WUpdateTools(List list) { - if (mode == 0) + return FUNCTION_NOT_ALLOWED_ERROR; + } + + #endregion Public Methods + + #region Protected Classes + + /// + /// Oggetto Modulo Blocco da PLC + /// + protected class PlcModBlock + { + #region Public Constructors + + /// + /// Deserializzazione da byte ad oggetto Param + /// + /// + public PlcModBlock(byte[] rawData) { - 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; + // converto i dati da byte grezzi ai 3 componenti... + Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); + EstimDuration = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray()); + EstimDelay = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray()); + PrevId_01 = S7.Net.Types.Int.FromByteArray(rawData.Skip(12).Take(2).ToArray()); + PrevId_02 = S7.Net.Types.Int.FromByteArray(rawData.Skip(14).Take(2).ToArray()); + PrevId_03 = S7.Net.Types.Int.FromByteArray(rawData.Skip(16).Take(2).ToArray()); } - else if (mode == 1) - return PROC_MODE.MDI; - else if (mode == 2) - return PROC_MODE.AUTO; - return PROC_MODE.ERROR; - } + #endregion Public Constructors - //Manage the Status - private PROC_STATUS ConvertToSTEPStatus(uint status) - { - switch (status) + #region Public Properties + + public int EstimDelay { get; set; } = 0; + public int EstimDuration { get; set; } = 0; + public short Id { get; set; } = 0; + public short PrevId_01 { get; set; } = 0; + public short PrevId_02 { get; set; } = 0; + public short PrevId_03 { get; set; } = 0; + + #endregion Public Properties + + #region Public Methods + + /// + /// Converte un singolo item in un array di byte per scrittura su PLC S7 + /// + /// + public byte[] convertToByte() { - case 0: return PROC_STATUS.IDLE; - case 1: return PROC_STATUS.RUN; - case 2: return PROC_STATUS.HOLD; + byte[] answ = new byte[18]; + Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(EstimDuration), 0, answ, 2, 4); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(EstimDelay), 0, answ, 6, 4); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_01), 0, answ, 12, 2); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_02), 0, answ, 14, 2); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_03), 0, answ, 16, 2); + return answ; } - 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; + #endregion Public Methods } /// - /// Check if PLC is responding to Ping + /// Oggetto Modulo Blocco RT da PLC /// - /// - private CmsError CheckS7Ping() + protected class PlcModBlockRT { + #region Public Constructors - // faccio ping... - if (testPing() != IPStatus.Success) - return PLC_IP_NOT_FOUND_ERROR; - return NO_ERROR; + /// + /// Deserializzazione da byte ad oggetto ParamRT + /// + /// + public PlcModBlockRT(byte[] rawData) + { + // converto i dati da byte grezzi ai 3 componenti... + Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); + ActualDuration = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray()); + ActualDelay = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray()); + // sono in realtà BIT STRUC --> reverse! + Stato = S7.Net.Types.Word.FromByteArray(rawData.Skip(10).Take(2).Reverse().ToArray()); + // calcolo bit... + Visible = (Stato & 1) == 1; + Running = (Stato & 2) == 2; + HasError = (Stato & 4) == 4; + Terminated = (Stato & 8) == 8; + } + + #endregion Public Constructors + + #region Private Properties + + private ushort Stato { get; set; } = 0; + + #endregion Private Properties + + #region Public Properties + + public int ActualDelay { get; set; } = 0; + public int ActualDuration { get; set; } = 0; + public bool HasError { get; set; } + public short Id { get; set; } = 0; + public bool Running { get; set; } + public bool Terminated { get; set; } = false; + public bool Visible { get; set; } + + #endregion Public Properties + + #region Public Methods + + /// + /// Converte un singolo item in un array di byte per scrittura su PLC S7 + /// + /// + public byte[] convertToByte() + { + // convero stato dai bit... + Stato = 0; + Stato += (ushort)(Visible ? 1 : 0); + Stato += (ushort)(Running ? 2 : 0); + Stato += (ushort)(HasError ? 4 : 0); + Stato += (ushort)(Terminated ? 8 : 0); + byte[] answ = new byte[12]; + Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ActualDuration), 0, answ, 2, 4); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ActualDelay), 0, answ, 6, 4); + Buffer.BlockCopy(S7.Net.Types.Word.ToByteArray(Stato), 0, answ, 10, 1); + return answ; + } + + #endregion Public Methods } - /// - /// Ping test to configured Ip address + /// Oggetto Parametro da PLC /// - /// - private IPStatus testPing() + protected class PlcParam { - 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; - } + #region Public Constructors - //Manage the Exception Launch - private CmsError ManageException(Exception ex) - { - // Catch the S7Net exceptions - if (ex.Message.Contains(NcNotFound) || ex.Message.Contains(NcNotFound2) || ex.Message.Contains(NcNotFound3) || ex.Message.Contains("Read() failed:")) + /// + /// Deserializzazione da byte ad oggetto Param + /// + /// + public PlcParam(byte[] rawData) { - Connected = false; - return NOT_CONNECTED_ERROR; + // converto i dati da byte grezzi ai 3 componenti... + Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); + SetpointHMI = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray()); + SetpointPLC = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray()); + ValMax = S7.Net.Types.DInt.FromByteArray(rawData.Skip(10).Take(4).ToArray()); + ValMin = S7.Net.Types.DInt.FromByteArray(rawData.Skip(14).Take(4).ToArray()); + UnitMeasure = S7.Net.Types.Word.FromByteArray(rawData.Skip(18).Take(2).ToArray()); } - else + + #endregion Public Constructors + + #region Public Properties + + public short Id { get; set; } = 0; + public int SetpointHMI { get; set; } = 0; + public int SetpointPLC { get; set; } = 0; + public ushort UnitMeasure { get; set; } = 0; + public int ValMax { get; set; } = 0; + public int ValMin { get; set; } = 0; + + #endregion Public Properties + + #region Public Methods + + /// + /// Converte un singolo item in un array di byte per scrittura su PLC S7 + /// + /// + public byte[] convertToByte() { - return CmsError.InternalError(ex.Message, ex); + byte[] answ = new byte[20]; + Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(SetpointHMI), 0, answ, 2, 4); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(SetpointPLC), 0, answ, 6, 4); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValMax), 0, answ, 10, 4); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValMin), 0, answ, 14, 4); + Buffer.BlockCopy(S7.Net.Types.Word.ToByteArray(UnitMeasure), 0, answ, 18, 2); + return answ; } + + #endregion Public Methods } - // Create and return CmsError object - private CmsError GetError(string message) + /// + /// Oggetto Parametro RT da PLC + /// + protected class PlcParamRT { - return CmsError.NcError(message); - } - - //Read Static Data - private CmsError ReadStaticNCData() - { - //Check if the NC is Connected - CmsError libraryError = CheckConnection(); - if (libraryError.IsError()) - return libraryError; - - + #region Public Constructors + /// + /// Deserializzazione da byte ad oggetto ParamRT + /// + /// + public PlcParamRT(byte[] rawData) + { + // converto i dati da byte grezzi ai 3 componenti... + Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray()); + ValueAct = S7.Net.Types.DInt.FromByteArray(rawData.Skip(4).Take(4).ToArray()); + Visible = S7.Net.Types.Boolean.GetValue(rawData[2], 0); + Enabled = S7.Net.Types.Boolean.GetValue(rawData[2], 1); + HasError = S7.Net.Types.Boolean.GetValue(rawData[2], 2); #if false - // prendo 2° valore(num max valori) - numByte = memByteRead[1]; - // poi prendo la stringa... - string outVal = ""; - for (int i = 2; i < numByte + 2; i++) - { - outVal += Char.ConvertFromUtf32(memByteRead[i]); - } + // calcolo bit... + Stato = S7.Net.Types.Word.FromByteArray(rawData.Skip(2).Take(2).Reverse().ToArray()); + Visible = (Stato & 1) == 1; + Enabled = (Stato & 2) == 2; + HasError = (Stato & 4) == 4; #endif - - - // 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 - { - - - List currMem = new List(); - libraryError = MEM_RWByteList(R, 0, STATIC_DATA.MemType, STATIC_DATA.Address, STATIC_DATA.SubAddress, 0, STATIC_DATA.Size, ref currMem); - if (libraryError.IsError()) - return libraryError; - - if (currMem.Count > 0) - { - // completare nuove variabili (matricola macchina, seriale PLC, firmware PLC) - S7Language = 0; - ConfChannelNo = 1; - Last_Static_Read = DateTime.Now; - Cnc_name = $"{currPLC.CPU}"; - // decodifico info! - byte[] memByteRead = currMem.Skip(0).Take(4).ToArray(); - int numByte = 0; - string outVal = ""; - for (int i = 0; i < 4; i++) - { - outVal += Char.ConvertFromUtf32(memByteRead[i]); - } - Cms_MachNumber = outVal; // matricola macchina, DB604.DBB6720..6723 - - memByteRead = currMem.Skip(4).Take(22).ToArray(); - outVal = ""; - numByte = memByteRead[1]; - for (int i = 2; i < numByte + 2; i++) - { - outVal += Char.ConvertFromUtf32(memByteRead[i]); - } - Cnc_SftVersion = outVal; // versione SW del firmware PLC/CNC | DB604.DBB6724..6745 - - memByteRead = currMem.Skip(26).Take(18).ToArray(); - outVal = ""; - numByte = memByteRead[1]; - for (int i = 2; i < numByte + 2; i++) - { - outVal += Char.ConvertFromUtf32(memByteRead[i]); - } - Cnc_SeriesNum = outVal; // seriale PLC/CNC | DB604.DBB6746..6763 - - memByteRead = currMem.Skip(44).Take(4).ToArray(); - outVal = ""; - outVal += Char.ConvertFromUtf32(memByteRead[0]); - for (int i = 1; i < 4; i++) - { - outVal += $"{memByteRead[i]}"; - } - PlcFirmware_SerialNum = outVal; // seriale PLC/CNC | DB604.DBB6764..6767 - - UnitOfMeasure = MILLIMETERS; - } - } - catch (Exception ex) - { - return ManageException(ex); - } } - return NO_ERROR; - } + #endregion Public Constructors - // Convert the internal Name var in Readable STEP Name - private string GetName(uint value) - { - string name = "Siemens "; - switch (value) + #region Private Properties + + private byte Stato { get; set; } = 0; + + #endregion Private Properties + + #region Public Properties + + public bool Enabled { get; set; } + public bool HasError { get; set; } + public short Id { get; set; } = 0; + public int ValueAct { get; set; } = 0; + public bool Visible { get; set; } + + #endregion Public Properties + + #region Public Methods + + /// + /// Converte un singolo item in un array di byte per scrittura su PLC S7 + /// + /// + public byte[] convertToByte() { - 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); + // convero stato dai bit... + Stato = 0; + Stato += (byte)(Visible ? 1 : 0); + Stato += (byte)(Enabled ? 2 : 0); + Stato += (byte)(HasError ? 4 : 0); + byte[] answ = new byte[8]; + Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2); + Buffer.BlockCopy(S7.Net.Types.Byte.ToByteArray(Stato), 0, answ, 2, 1); + Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValueAct), 0, answ, 4, 4); + return answ; } - return littleEndianValues; + #endregion Public Methods } - 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; - } + #endregion Protected Classes //private void CheckData(object obj, List config) //{ @@ -5522,199 +5986,5 @@ namespace CMS_CORE_Library.S7Net // 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 - - } - - - internal static class MEMORY_ADDRESS - { - // A) THERMO SPECIAL MEMORY - - // Main DB Table - internal const int TABLE = 604; - - // assi - internal static MEMORY_CELL AXES_RTDATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 615, 0, 768); - internal static MEMORY_CELL AXES_INFO = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 0, 896); - - // aree Parametri - internal static MEMORY_CELL PARAMETER_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 600, 20, 8000); - internal static MEMORY_CELL PARAMETER_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 601, 8, 3200); - - // recipe edit confirmation/cancel strobe/ack - internal static MEMORY_CELL PARAMETER_EDIT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); - internal static MEMORY_CELL PARAMETER_EDIT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); - - // Mode request strobe/ack - internal static MEMORY_CELL REQ_MODE_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); - internal static MEMORY_CELL REQ_MODE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); - - // Prod strobe/ack - internal static MEMORY_CELL PROD_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); - internal static MEMORY_CELL PROD_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); - - // strobe received from PLC - internal static MEMORY_CELL REQ_CONF_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2); - internal static MEMORY_CELL REQ_CONF_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2); - - // aree Moduli - internal static MEMORY_CELL MODULE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 602, 18, 2304); - internal static MEMORY_CELL MODULE_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 603, 12, 1536); - - // riscaldi - internal static MEMORY_CELL RISC_VU_MIN = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 513, 0, 2); - internal static MEMORY_CELL RISC_OCC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 64, 64); - internal static MEMORY_CELL RISC_PLC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 627, 0, 1024); //internal static MEMORY_CELL RISC_PLC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 128, 1024); //valore PRE thermoCam - internal static MEMORY_CELL RISC_CHP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 614, 0, 1024); - internal static MEMORY_CELL RISC_CFI_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 2176, 1024); - internal static MEMORY_CELL RISC_ICH_MIN_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 3200, 4096); - internal static MEMORY_CELL RISC_OCS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 9472, 64); - internal static MEMORY_CELL RISC_ESP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 9728, 1024); - 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); - internal static MEMORY_CELL TCAM_CH_ENAB_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 4, 128); - internal static MEMORY_CELL TCAM_TEMP_REQ_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 624, 0, 2048); - internal static MEMORY_CELL TCAM_TEMP_ACT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 625, 0, 2048); - - - // produzione - internal static MEMORY_CELL PROCESS_PROD_INFO = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 606, 0, 52); - internal static MEMORY_CELL PROCESS_PROD_CYCLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 22); - - internal static MEMORY_CELL PROCESS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 2); - - // Machine data - internal static MEMORY_CELL STATIC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 48); - internal static MEMORY_CELL NEW_MATR_MACC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 4); - internal static MEMORY_CELL VERS_SW_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6724, 22); - internal static MEMORY_CELL SER_NUM_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6746, 22); - internal static MEMORY_CELL FIRMWARE_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6764, 4); - - // generic machine gauge data - internal static MEMORY_CELL MACHINE_GAUGE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 6, 16); - - // watchdog - internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 1); - - // status/command data - internal static MEMORY_CELL STATUS_CMD_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 4); - - - - // B) GEN memory (NOT Thermo) - 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, 6542, 4); - //internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2576, 2); - - internal static MEMORY_CELL USER_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6552, 16); - internal static MEMORY_CELL USER_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6568, 16); - internal static MEMORY_CELL USER_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6584, 16); - internal static MEMORY_CELL USER_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6600, 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, 2318, 128); - - - - // C) STD MEM (need check!) FIXME TODO - 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 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 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.Siemens_DB, TABLE, 6768, 1); - internal static MEMORY_CELL M156_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6770, 1); - internal static MEMORY_CELL M156_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6772, 1); - internal static MEMORY_CELL M156_INPUT_ID_LIST = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6774, 2); - internal static MEMORY_CELL M156_RESPONSE_MEMORY = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6776, 4); - internal static MEMORY_CELL KEYBOARD_STAR_MEMORY = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6780, 2); - - 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); - - - //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); - - } } \ No newline at end of file diff --git a/CMS_CORE_Library/Utils/Nc_Utils.cs b/CMS_CORE_Library/Utils/Nc_Utils.cs index c12d8ff..cb90055 100644 --- a/CMS_CORE_Library/Utils/Nc_Utils.cs +++ b/CMS_CORE_Library/Utils/Nc_Utils.cs @@ -166,6 +166,30 @@ namespace CMS_CORE_Library.Utils return String.Empty; } + internal static Dictionary convToDictIntBol(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; + } + internal static Dictionary convToDictIntInt(List origVal) + { + Dictionary answ = new Dictionary(); + for (int i = 0; i < origVal.Count; i++) + { + answ.Add(i, origVal[i]); + } + return answ; + } + // Convert one integer in array of bools internal static bool[] IntToBits(int val) { @@ -316,6 +340,19 @@ namespace CMS_CORE_Library.Utils return (b & (1 << bitNumber)) != 0; } + public static int SetBitOne(this int value, int position) + { + // Set a bit at position to 1. + return value |= (1 << position); + } + + public static int SetBitZero(this int value, int position) + { + // Set a bit at position to 0. + return value & ~(1 << position); + } + + public static CultureInfo GetCultureFromThreeLetter(string threeLetter) { // Get culture info from three letter iso standard