using CMS_CORE_Library; using CMS_CORE_Library.Demo; using CMS_CORE_Library.Fanuc; using CMS_CORE_Library.Models; using CMS_CORE_Library.Osai; using CMS_CORE_Library.Siemens; using Step.Database.Controllers; using Step.Model.DatabaseModels; using Step.Model.DTOModels; using Step.Model.DTOModels.AlarmModels; using Step.Model.DTOModels.MaintenanceModels; using Step.Model.DTOModels.Scada; using Step.Utils; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using static CMS_CORE_Library.Models.DataStructures; using static Step.Config.ServerConfig; using static Step.Model.Constants; namespace Step.NC { public class NcHandler : IDisposable { public Nc numericalControl; public NcHandler() => // Choose NC numericalControl = SetNumericalControl(); public void Dispose() { if (NcConfig.NcVendor != NC_VENDOR.SIEMENS) numericalControl.NC_Disconnect(); } public void Disconnect() { numericalControl.NC_Disconnect(); } public CmsError Connect() { // Connect NC if (!numericalControl.NC_IsConnected()) return numericalControl.NC_Connect(); return null; } public Nc SetNumericalControl() { // Return new Numerical control instance choosed from the configuration switch (NcConfig.NcVendor) { case NC_VENDOR.DEMO: return new Nc_Demo(NcConfig.NcIpAddress, NcConfig.NcPort); case NC_VENDOR.FANUC: return new Nc_Fanuc(NcConfig.NcIpAddress, NcConfig.NcPort, 2000); case NC_VENDOR.SIEMENS: return new Nc_Siemens(2000); case NC_VENDOR.OSAI: return new Nc_Osai(NcConfig.NcIpAddress, NcConfig.NcPort, 2000); } return null; } #region Read Data #region Axes public CmsError GetAxesPositions(out List axes) { axes = new List(); // Get NC max process number ushort maxProcNumber = 0; CmsError cmsError = numericalControl.NC_RProcessesNum(ref maxProcNumber); if (cmsError.errorCode != 0) return cmsError; // For each process for (ushort i = 1; i <= maxProcNumber; i++) { cmsError = GetAxesPositionsByProcess(i, out DTOAxesModel axis); if (cmsError.errorCode != 0) return cmsError; axes.Add(axis); } return cmsError; } public CmsError GetAxesPositionsBySelectedProcess(out DTOAxesModel axes) { axes = new DTOAxesModel(); // Get selectedProcess process number ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; if (selectedProcess > 0) cmsError = GetAxesPositionsByProcess(selectedProcess, out axes); return cmsError; } public CmsError GetAxesPositionsByProcess(ushort processNum, out DTOAxesModel axes) { axes = new DTOAxesModel(); CmsError cmsError = numericalControl.AXES_RInterpPosition(processNum, ref axes.interpolated); if (cmsError.errorCode != 0) return cmsError; cmsError = numericalControl.AXES_RMachinePosition(processNum, ref axes.machine); if (cmsError.errorCode != 0) return cmsError; cmsError = numericalControl.AXES_RProgrPosition(processNum, ref axes.programmePos); if (cmsError.errorCode != 0) return cmsError; cmsError = numericalControl.AXES_RDistanceToGo(processNum, ref axes.toGo); if (cmsError.errorCode != 0) return cmsError; //numericalControl.AXES_RFollowingError(1, ref axes.followingErr); return cmsError; } public CmsError ReadAxisData(out List axesNames) { axesNames = new List(); List plcAxes = new List(); // Read selected process ushort selectedProcess = 0; CmsError cmsError = numericalControl.PROC_RSelectedProcess(ref selectedProcess); if (cmsError.IsError()) return cmsError; if (selectedProcess != 0) { // Read axes names cmsError = numericalControl.AXES_RAxesNames(selectedProcess, ref plcAxes); axesNames = plcAxes.Select(x => new DTOAxisNameModel() { Id = x.Id, Name = x.Name, IsSelectable = x.IsSelectable, Type = x.Type.ToString() }).ToList(); } return cmsError; } #endregion Axes public CmsError ManageWatchdog() { return numericalControl.PLC_RWManageWatchdog(); } public CmsError GetNcGenericData(out DTONcGenericDataModel genericData) { genericData = new DTONcGenericDataModel(MachineConfig.Model); // Get date time DateTime dateTime = new DateTime(); CmsError cmsError = numericalControl.NC_RDateTime(ref dateTime); if (cmsError.errorCode != 0) return cmsError; genericData.DateTime = dateTime; // Get language CultureInfo lang = new CultureInfo("en"); cmsError = numericalControl.NC_RLanguage(ref lang); if (cmsError.errorCode != 0) return cmsError; genericData.Language = lang.TwoLetterISOLanguageName; string tmpInfo = ""; // Get serial number cmsError = numericalControl.NC_RSerialNumber(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.SerialNumber = tmpInfo; // Get software version cmsError = numericalControl.NC_RSoftwareVersion(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.NcSoftwareVersion = tmpInfo; // Get model name cmsError = numericalControl.NC_RModelName(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.NcModel = tmpInfo; // Get machine number cmsError = numericalControl.NC_RMachineNumber(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.CmsMachineIdNumber = tmpInfo; // Get max process number ushort procNum = 0; cmsError = numericalControl.NC_RProcessesNum(ref procNum); if (cmsError.IsError()) return cmsError; // Max process number genericData.ProcessNumber = procNum; // Get Installation Date genericData.InstallationDate = DateTime.Parse(NcConfig.InstallationDate); // Get PLC version genericData.PlcVersion = "1.0.0"; // Get PLC version cmsError = numericalControl.NC_RUnitOfMeasure(ref tmpInfo); if (cmsError.errorCode != 0) return cmsError; genericData.UnitOfMeasurement = tmpInfo; return cmsError; } public CmsError GetNcAlarms(out DTOAlarmsModel alarms) { alarms = new DTOAlarmsModel(); List tmpAlarms = new List(); // Read NC active alarms CmsError cmsError = numericalControl.NC_RActiveAlarms(ref tmpAlarms); if (cmsError.errorCode != 0) return cmsError; // Create response list from NC data foreach (AlarmModel ncAlarm in tmpAlarms) { alarms.NcAlarms.Add(new GenericAlarmModel() { Id = ncAlarm.Id, Message = ncAlarm.Message, DateTime = DateTime.Now, RestorationIsEnabled = false }); } // Select distints //alarms.NcAlarms = alarms.NcAlarms?.GroupBy(x => x.Id).Select(x => x.First()).ToList(); // Get NC max process number ushort maxProcNumber = 0; cmsError = numericalControl.NC_RProcessesNum(ref maxProcNumber); if (cmsError.errorCode != 0) return cmsError; // For each process for (ushort i = 1; i <= maxProcNumber; i++) { // Get process active alarms numericalControl.PROC_RActiveAlarms(i, ref tmpAlarms); // Create response list from NC data foreach (AlarmModel processAlarm in tmpAlarms) { alarms.ProcessAlarms.Add(new ProcessAlarmModel() { Id = processAlarm.Id, Message = processAlarm.Message, Process = processAlarm.Process, DateTime = DateTime.Now, RestorationIsEnabled = false }); } } List plcAlarms = new List(); // Read PLC Active Messages cmsError = numericalControl.PLC_RActiveMessages(ref plcAlarms); if (cmsError.IsError()) return cmsError; bool restorationIsEnabled = false; foreach (PlcAlarmModel plcAlarm in plcAlarms) { var configuredAlarm = InitialAlarmsConfig.Where(x => x.PlcId == plcAlarm.Id).FirstOrDefault(); if (configuredAlarm == null) restorationIsEnabled = false; else restorationIsEnabled = configuredAlarm.RestoreIsActive; // Create response list from plc data alarms.PlcAlarms.Add(new DTOPlcAlarmModel() { Id = plcAlarm.Id, IsWarning = plcAlarm.IsWarning, Process = plcAlarm.Process, RestorationIsActive = plcAlarm.RestorationIsActive, DateTime = DateTime.Now, RestorationIsEnabled = restorationIsEnabled }); } if (cmsError.errorCode != 0) return cmsError; return cmsError; } public CmsError GetPowerOnData(out DTOPowerOnDataModel resultPowerOnData) { resultPowerOnData = new DTOPowerOnDataModel(); // Init object PreAndPostPowerOnModel prePostPowerOn = new PreAndPostPowerOnModel { PostPowerOn = new PostPowerOnModel(), PrePowerOn = new PrePowerOnModel() }; // Read pre and post power on data CmsError cmsError = numericalControl.PLC_RPowerOnData(ref prePostPowerOn); if (cmsError.IsError()) return cmsError; // Set return object resultPowerOnData.PrePowerOn = prePostPowerOn.PrePowerOn; resultPowerOnData.PostPowerOn = prePostPowerOn.PostPowerOn; // Read axes procedure data from cmsError = numericalControl.PLC_RAxesResetData(ref resultPowerOnData.AxisReset); return cmsError; } public CmsError GetProcessesData(out DTOProcessesDataModel processesData) { processesData = new DTOProcessesDataModel(); // Get NC max process number ushort maxProcNumber = 0; CmsError cmsError = numericalControl.NC_RProcessesNum(ref maxProcNumber); if (cmsError.errorCode != 0) return cmsError; PROC_STATUS status = PROC_STATUS.IDLE; // For each process get info for (ushort i = 1; i <= maxProcNumber; i++) { ProcessDataModel tmpProcPP = new ProcessDataModel(); // Get process status cmsError = numericalControl.PROC_RStatusAndData(i, ref tmpProcPP); if (cmsError.IsError()) return cmsError; // if at least one process is in run, NC is running // Add to list processesData.processes.Add(new ProcessModel() { Id = tmpProcPP.Id, IsInAlarm = tmpProcPP.IsInAlarm, PartProgramName = tmpProcPP.PartProgramName, Reps = tmpProcPP.Reps, Status = tmpProcPP.Status, Type = tmpProcPP.Type, Visible = tmpProcPP.Visible, CanLoadProgram = tmpProcPP.CanLoadProgram }); if (tmpProcPP.IsSelected && processesData.SelectedProcess == 0) { processesData.SelectedProcess = (ushort)tmpProcPP.Id; processesData.CanLoadProgram = tmpProcPP.CanLoadProgram; } // Check if there are running process if (!processesData.IsRunning) { // Get process status cmsError = numericalControl.PROC_RStatus(i, ref status); if (status == PROC_STATUS.RUN || status == PROC_STATUS.HOLD) processesData.IsRunning = true; else status = PROC_STATUS.IDLE; } } // Read selected axes cmsError = numericalControl.AXES_RSelectedAxis(ref processesData.SelectedAxis); if (cmsError.IsError()) return cmsError; QueueStatusModel queueStatus = new QueueStatusModel(); // Get queue data cmsError = numericalControl.FILES_RQueueDataByProcess(ref queueStatus, processesData.SelectedProcess); if (cmsError.IsError()) return cmsError; // Get selectedProcessData SelectedProcessData selectedData = new SelectedProcessData(); cmsError = numericalControl.PROC_RSelectedProcessData(processesData.SelectedProcess, ref selectedData); if (cmsError.IsError()) return cmsError; String UMeas = "mm"; // Get process status cmsError = numericalControl.NC_RUnitOfMeasure(ref UMeas); if (cmsError.IsError()) return cmsError; // Set data processesData.QueueStatus = queueStatus.Status; processesData.StartStopQueueEnabled = queueStatus.StartStopQueueEnabled; processesData.ActiveOrigin = selectedData.Origin; processesData.ActiveOffsetId = selectedData.ActiveOffsetId; processesData.UnitMeasure = UMeas; return cmsError; } public CmsError GetFunctionsMappedWithNC(out List functionsAccessList) { functionsAccessList = new List(); // Read plc functionality List functionalityList = null; CmsError cmsError = numericalControl.PLC_RFunctionAccess(ref functionalityList); // If empty return if (functionalityList == null || functionalityList.Count == 0) return cmsError; using (FunctionsAccessController functionsAccessController = new FunctionsAccessController()) { // Map plc and database data functionsAccessList = functionsAccessController.GetFunctionsMappedWithPlc(functionalityList); } return cmsError; } public CmsError GetMainenancesCounter(out List counters) { // List of PLC counters counters = new List(); // Get counters values from PLC CmsError cmsError = numericalControl.PLC_RMachineCounters(ref counters); return cmsError; } public CmsError GetMaintenanceDataById(int maintenanceId, int userId, out DTOMaintenanceModel dTOMaintenance) { dTOMaintenance = null; CmsError cmsError = GetMaintenancesWithPermissions(out List maintenance, userId); if (cmsError.IsError()) return cmsError; dTOMaintenance = maintenance.Where(x => x.Id == maintenanceId).FirstOrDefault(); return cmsError; } public CmsError GetMaintenancesWithPermissions(out List dtoMaintenancesModel, int userId) { // Return value dtoMaintenancesModel = new List(); // Get counters values from PLC CmsError cmsError = GetMainenancesCounter(out List counters); if (cmsError.IsError()) return cmsError; using (MaintenancesController maintenancesController = new MaintenancesController()) { // Get the last performed maintenance for each maintenance List performedMaintenances = maintenancesController.FindLastPerformedMaintenances(); // Get all the active maintenances List maintenances = maintenancesController.FindAll(); // TODO db or config file? double percentage = 0; TimeSpan missingDays = new TimeSpan(); CounterModel counter = new CounterModel(); bool canEdit = false; bool canPerform = false; foreach (var currMaintenance in maintenances) { // Get matching last performed maintenance for current maintenance PerformedMaintenanceModel performed = performedMaintenances.Find(x => x.MaintenanceId == currMaintenance.MaintenanceId); switch (currMaintenance.Type) { case MAINTENANCE_TYPE.MACHINE_INTERVAL: { // Get matching counter for the current maintenance counter = counters.Find(x => x.Id == currMaintenance.CounterId); // Convert from seconds to minuts var counterVal = counter.Value / 60; int perfVal = 0; if (performed != null) perfVal = performed.CounterValue; // Calc percentage = PLC - PERFORMED VALUE * 100 / interval percentage = ((counterVal - perfVal) * 100) / SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value); missingDays = TimeSpan.FromMinutes(-1 * (counterVal - perfVal - SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value))); } break; case MAINTENANCE_TYPE.EXP_DATE: { // Already performed if (performed != null) { percentage = 100; missingDays = TimeSpan.Zero; } else { percentage = ((DateTime.Now - currMaintenance.CreationDate).TotalMinutes * 100) / (currMaintenance.Deadline - currMaintenance.CreationDate).TotalMinutes; // TimeSpan.FromTicks((currMaintenance.Deadline.Ticks)).TotalMinutes missingDays = currMaintenance.Deadline - DateTime.Now; counter = new CounterModel(); } } break; case MAINTENANCE_TYPE.TIME_INTERVAL: { // Get last performed, default value is maintenance creation date DateTime perfDate = currMaintenance.CreationDate; if (performed != null) perfDate = performed.Date; // Now - last performed = elapsed interval since last maintenance TimeSpan timePassedFromLastMaint = DateTime.Now.Subtract(perfDate); // Convert in minutes double minutesPassedFromLastMaint = timePassedFromLastMaint.TotalMinutes; // percentage = Passed minutes since last maintenance * 100 / Interval percentage = (minutesPassedFromLastMaint * 100) / SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value); missingDays = TimeSpan.FromMinutes(-1 * (minutesPassedFromLastMaint - SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value))); counter = new CounterModel(); } break; } canEdit = false; using (MachinesUsersController machineUsersController = new MachinesUsersController()) { if (currMaintenance.UserId != null) { // Check if user can edit the maintenance -> caller id - maintenance user id int comparision = machineUsersController.CompareUsersRole(userId, currMaintenance.UserId.Value, MachineConfig.MachineId); if (comparision >= 0) canPerform = canEdit = true; } else { canEdit = false; canPerform = machineUsersController.UserIsCmsAdmin(MachineConfig.MachineId, userId); } } dtoMaintenancesModel.Add(new DTOMaintenanceModel() { Id = currMaintenance.MaintenanceId, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title, CreationDate = currMaintenance.CreationDate, Deadline = currMaintenance.Deadline, Description = currMaintenance.Description, Interval = currMaintenance.Interval, LastExpirationDate = currMaintenance.LastExpirationDate, LastPerformedDate = performed?.Date, Type = currMaintenance.Type.ToString(), UnitOfMeasure = currMaintenance.UnitOfMeasure.ToString(), PercentageOfCompletion = percentage >= 0 && percentage < 100 ? Convert.ToInt32(percentage) : 100, MissingDays = missingDays, PlcCounter = counter.Value, CreatedByCms = currMaintenance.UserId == null, CanEdit = canEdit, CanPerform = canPerform, Maintainer = performed?.Maintainer == null ? null : (DTOMessageUserModel)performed.Maintainer }); } } return cmsError; } public CmsError GetExpiredMaintenances(out List expiredMaintenance) { // Return value expiredMaintenance = new List(); // Get counters values from PLC CmsError cmsError = GetMainenancesCounter(out List counters); if (cmsError.IsError()) return cmsError; using (MaintenancesController maintenancesController = new MaintenancesController()) { // Get the last performed maintenance for each maintenance List performedMaintenances = maintenancesController.FindLastPerformedMaintenances(); // Get all the active maintenances List maintenances = maintenancesController.FindAll(); // TODO db or config file? foreach (var currMaintenance in maintenances) { // Get matching last performed maintenance for current maintenance var performed = performedMaintenances.Find(x => x.MaintenanceId == currMaintenance.MaintenanceId); switch (currMaintenance.Type) { case MAINTENANCE_TYPE.MACHINE_INTERVAL: { // Get matching counter for the current maintenance var counter = counters.Find(x => x.Id == currMaintenance.CounterId); int perfVal = 0; if (performed != null) perfVal = performed.CounterValue; // MAINTENANCE_INTERVAL <= PLC - LASTPERFORMED if (SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value) <= (counter.Value / 60) - perfVal) { // Update last expiration date if null if (currMaintenance.LastExpirationDate == null) { maintenancesController.UpdateLastExpirationDate(currMaintenance.MaintenanceId, DateTime.Now); currMaintenance.LastExpirationDate = DateTime.Now; } // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() { Id = currMaintenance.MaintenanceId, ExpirationDate = (DateTime)currMaintenance.LastExpirationDate, CreatedByCms = currMaintenance.UserId == null, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title }); } } break; case MAINTENANCE_TYPE.EXP_DATE: { // Already performed if (performed != null) break; // DEADLINE <= NOW if (currMaintenance.Deadline <= DateTime.Now) { maintenancesController.UpdateLastExpirationDate(currMaintenance.MaintenanceId, currMaintenance.Deadline); currMaintenance.LastExpirationDate = currMaintenance.Deadline; // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() { Id = currMaintenance.MaintenanceId, ExpirationDate = currMaintenance.Deadline, CreatedByCms = currMaintenance.UserId == null, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title, }); } } break; case MAINTENANCE_TYPE.TIME_INTERVAL: { // Get last performed, default value is maintenance creation date DateTime perfDate = currMaintenance.CreationDate; if (performed != null) perfDate = performed.Date; // Now - last performed = elapsed interval since last maintenance TimeSpan timePassedFromLastMaint = DateTime.Now.Subtract(perfDate); // Convert in minutes double minutesPassedFromLastMaint = timePassedFromLastMaint.TotalMinutes; // Interval - passed minutes since last maintenance if (SupportFunctions.ConvertInMinutes(currMaintenance.Interval.Value, currMaintenance.UnitOfMeasure.Value) <= minutesPassedFromLastMaint) { // Update last expiration date if (currMaintenance.LastExpirationDate == null) { // Exp date = now - ( expiration intervall) DateTime expirationDate = DateTime.Now.Subtract(TimeSpan.FromMinutes(minutesPassedFromLastMaint - currMaintenance.Interval.Value)); maintenancesController.UpdateLastExpirationDate(currMaintenance.MaintenanceId, expirationDate); currMaintenance.LastExpirationDate = expirationDate; } // Add item to return list expiredMaintenance.Add(new DTOExpiredMaintenanceModel() { Id = currMaintenance.MaintenanceId, ExpirationDate = (DateTime)currMaintenance.LastExpirationDate, CreatedByCms = currMaintenance.UserId == null, Title = currMaintenance.UserId == null ? "" : currMaintenance.Title, }); } } break; } } } return cmsError; } public CmsError GetUserSoftKeys(out List softKeys) { softKeys = new List(); List plcSoftKeys = new List(); // Get softkeys data from PLC CmsError cmsError = numericalControl.PLC_RUserSoftKeys(ref plcSoftKeys); if (cmsError.IsError() || plcSoftKeys.Count == 0) return cmsError; foreach (var softKey in SoftKeysConfig) { // Check type of the selected softkey if (softKey.Type == SOFTKEY_TYPE.GROUP) { // Foreach subkey create a softkey foreach (var subkey in softKey.SubKeys) { // Find the plc matching data var plcSoftKey = plcSoftKeys.Find(x => x.Id == subkey.PlcId); // Create and add new user softkey model softKeys.Add(new DTOUserSoftKeyModel() { Id = subkey.Id, Active = plcSoftKey.Active, Category = softKey.Category, Value = plcSoftKey.Value }); } softKeys.Add(new DTOUserSoftKeyModel() { Id = softKey.Id, Category = softKey.Category, Visible = softKey.IsVisible }); } else { // Find the plc matching data var plcSoftKey = plcSoftKeys.Find(x => x.Id == softKey.PlcId); softKeys.Add(new DTOUserSoftKeyModel() { Id = softKey.Id, Active = plcSoftKey.Active, Category = softKey.Category, Visible = softKey.IsVisible, Value = plcSoftKey.Value }); } } return cmsError; } public CmsError GetNcSoftKeys(out List ncSoftKeys) { ncSoftKeys = new List(); List plcSoftKeys = new List(); // Get Nc softkeys data from PLC CmsError cmsError = numericalControl.PLC_RNcSoftKeys(ref plcSoftKeys); if (cmsError.IsError() || plcSoftKeys.Count == 0) return cmsError; foreach (var softKey in NcSoftKeysConfig) { // Find the plc matching data var plcSoftKey = plcSoftKeys.Find(x => x.Id == softKey.Id); // Create and add Nc softkey model ncSoftKeys.Add(new DTONcSoftKeyModel() { Id = softKey.Id, Active = plcSoftKey.Active, Value = plcSoftKey.Value }); } return cmsError; } public CmsError GetHeadsData(out List heads) { // Returned value heads = new List(); // Number of configured heads int headsNumber = HeadsConfig.Count; List plcHeads = new List(); // Read value from PLC CmsError cmsError = numericalControl.PLC_RHeadsData(plcHeads, headsNumber); if (cmsError.IsError()) return cmsError; foreach (var head in plcHeads) { // Get current head config var configuredHead = HeadsConfig.Find(x => x.Id == head.Id); // Create different model according on type switch (configuredHead.Type) { case HEAD_TYPE.SPINDLE: { heads.Add(new DTOSpindleModel() { Id = head.Id, Process = head.Process, Type = configuredHead.Type.ToString(), FixedHead = configuredHead.FixedHead, inWarning = head.Load_Abrasive >= configuredHead.WarningLimit, inAlarm = head.Load_Abrasive >= configuredHead.AlarmLimit, OverrideEditable = head.OverrideEditable, ActualSpeed = head.ActualSpeed_Pressure, Load = head.Load_Abrasive, MountedTool = (ushort)head.MountedTool_Vacum, Override = head.Override, IsActive = head.IsActive, IsSelected = head.IsSelected, AbrasiveIsActive = head.AbrasiveIsActive, Configured = head.Configured, Rotation = head.Rotation, WorkedTime = head.WorkedTime, ToolData = head.Tool == null ? null : new DTOToolInSpindleModel() { ChildId = head.Tool.ChildId, ToolName = head.Tool.ToolName } }); } break; case HEAD_TYPE.AWJ: { float vacumValue = (float)head.MountedTool_Vacum / 100; heads.Add(new DTOAbrasiveWaterJet() { Id = head.Id, Process = head.Process, Type = configuredHead.Type.ToString(), FixedHead = configuredHead.FixedHead, inWarning = vacumValue >= configuredHead.WarningLimit, inAlarm = vacumValue >= configuredHead.AlarmLimit, OverrideEditable = head.OverrideEditable, ActualPressure = head.ActualSpeed_Pressure, Abrasive = Convert.ToUInt16(head.Load_Abrasive), Vacum = vacumValue, Override = head.Override, IsActive = head.IsActive, IsSelected = head.IsSelected, AbrasiveIsActive = head.AbrasiveIsActive, WorkedTime = head.WorkedTime }); } break; case HEAD_TYPE.WJ: { heads.Add(new DTOWaterJet() { Id = head.Id, Process = head.Process, Type = configuredHead.Type.ToString(), FixedHead = configuredHead.FixedHead, inAlarm = false, inWarning = false, ActualPressure = head.ActualSpeed_Pressure, OverrideEditable = head.OverrideEditable, Override = head.Override, IsActive = head.IsActive, IsSelected = head.IsSelected, AbrasiveIsActive = head.AbrasiveIsActive, WorkedTime = head.WorkedTime }); } break; } } return cmsError; } public CmsError GetM155Data(out List data) { data = new List(); List ncData = new List(); CmsError cmsError = numericalControl.PLC_ROperatorInputIsNeeded(ref ncData); if (cmsError.IsError()) return cmsError; data = ncData.Select(x => new DTOM155InputModel() { Buttons = x.Buttons, IsNeeded = x.IsNeeded, Message = x.Message, Process = x.Process, Type = x.Type.ToString(), Value = x.Value }).ToList(); return NO_ERROR; } public CmsError GetM154Data(out List data, out bool MTCStatus) { MTCStatus = false; data = new List(); return numericalControl.PLC_RM154Data(ref data, ref MTCStatus); } public CmsError WriteM154Ack(int processId) { return numericalControl.PLC_W154ManageAck(processId); } public CmsError ReadScadasData(List schemasToRead, out List scadas) { CmsError cmsError = NO_ERROR; scadas = new List(); List alreadyReadScada = new List(); foreach (var schema in schemasToRead) { // Avoid duplicated reads if (!alreadyReadScada.Contains(schema.Id)) { // Read one schema cmsError = ReadScadaData(schema, out DTOScadaModel scadaValue); if (cmsError.IsError()) return cmsError; // Add value to return list scadas.Add(scadaValue); // Add id to read scada alreadyReadScada.Add(schema.Id); } } return cmsError; } public CmsError ReadScadaData(ScadaSchemaModel scadaSchema, out DTOScadaModel scadaValue) { CmsError cmsError = NO_ERROR; scadaValue = new DTOScadaModel() { Id = scadaSchema.Id, Name = scadaSchema.Name, IsInProductionPage = scadaSchema.IsInProductionPage, Buttons = new List() }; // Cycle inside layers foreach (var layer in scadaSchema.Layers) { object val = null; object val2 = null; // Cycle through elements, use the max number of elements between layer components in order to be optimized for (int i = 0; i < GetMaxCountBetweenLayerComponents(layer); i++) { if (layer.Buttons.ElementAtOrDefault(i) != null) { // Read enabled from PLC cmsError = numericalControl.PLC_RScadaValue(layer.Buttons[i].Status.MemEnabledIndex, SCADA_MEM_TYPE.BOOL, ref val); if (cmsError.IsError()) return cmsError; // Populate & add new object into scada model scadaValue.Buttons.Add(new DTOScadaButtonModel() { Id = layer.Buttons[i].Id, Enabled = Convert.ToBoolean(val) }); } if (layer.Images.ElementAtOrDefault(i) != null) { // Read isVisible from PLC cmsError = numericalControl.PLC_RScadaValue(layer.Images[i].Status.MemVisibleIndex, SCADA_MEM_TYPE.BOOL, ref val); if (cmsError.IsError()) return cmsError; var negate = layer.Images[i].Status.Negate; // Populate & add new object into scada model scadaValue.Images.Add(new DTOScadaImageModel() { Id = layer.Images[i].Id, IsVisible = negate ? !Convert.ToBoolean(val) : Convert.ToBoolean(val) }); } if (layer.ProgressBars.ElementAtOrDefault(i) != null) { // Read value from PLC cmsError = numericalControl.PLC_RScadaValue(layer.ProgressBars[i].MemValueIndex, SCADA_MEM_TYPE.BYTE, ref val); if (cmsError.IsError()) return cmsError; // Populate & add new object into scada model scadaValue.ProgressBars.Add(new DTOScadaProgressBarModel() { Id = layer.ProgressBars[i].Id, Value = Convert.ToByte(val) }); } if (layer.Inputs.ElementAtOrDefault(i) != null && layer.Inputs[i].Status.Action == "read") { // Read isVisible from PLC cmsError = numericalControl.PLC_RScadaValue(layer.Inputs[i].Status.MemEnabledIndex, SCADA_MEM_TYPE.BOOL, ref val); if (cmsError.IsError()) return cmsError; SCADA_MEM_TYPE type = SupportFunctions.GetMemTypeFromString(layer.Inputs[i].Status.Type); // Read value from PLC cmsError = numericalControl.PLC_RScadaValue(layer.Inputs[i].Status.MemValueIndex, type, ref val2); if (cmsError.IsError()) return cmsError; // if type is real approximate to configurated decimal digits if (type == SCADA_MEM_TYPE.REAL) { double tmpVal = Math.Round(Convert.ToDouble(val2), layer.Inputs[i].Status.Round); val2 = tmpVal; } // Populate & add new object into scada model scadaValue.Inputs.Add(new DTOScadaInputModel() { Id = layer.Inputs[i].Id, Value = new DTOScadaValueModel() { IsEnabled = Convert.ToBoolean(val), Value = val2 } }); } } } return cmsError; } #endregion Read Data #region Write data public CmsError PutNcSoftKeyClick(uint id) { // Write Nc softkey press to plc CmsError cmsError = numericalControl.PLC_WNcSoftKey(id); return cmsError; } public CmsError PutUserSoftKeyClick(uint id) { // Write user softkey press to plc return numericalControl.PLC_WUserSoftKey(id); } public CmsError RefreshAlarm(uint id) { // Write in memory the request to refresh the alarm return numericalControl.PLC_WRefreshMessage(id); } public CmsError RestoreAlarm(uint id) { // Write in memory the request to restore the alarm return numericalControl.PLC_WRestoreMessage(id); } public CmsError RefreshAllAlarms() { return numericalControl.PLC_WRefreshAllMessages(); } public CmsError PutSelectProcess(ushort procNumber) { return numericalControl.PROC_WSelectProcess(procNumber); } public CmsError PutSelectAxis(byte axisId) { return numericalControl.AXES_WSelectAxis(axisId); } public CmsError PutOverride(uint id, string action) { HEAD_OVERRIDE_SIGN sign = HEAD_OVERRIDE_SIGN.MINUS; if (action == "plus") sign = HEAD_OVERRIDE_SIGN.PLUS; return numericalControl.PLC_WHeadOverride(id, sign); } public CmsError PutPowerOnData(uint id) { // Set to true power on data by id return numericalControl.PLC_WPowerOnData(id, true); } public CmsError SetActiveLanguage(CultureInfo language) { // Set to true power on data by id return numericalControl.NC_WLanguage(language); } public CmsError SetActiveScreen(short screen) { // Set to true power on data by id return numericalControl.NC_SetScreenVisible((Nc.SCREEN_PAGE)screen); } public CmsError WriteM155Data(int process, double responseValue) { return numericalControl.PLC_WOperatorInputResponse(process, responseValue); } public CmsError WriteScada(string memIndex, SCADA_MEM_TYPE memType, object value) { return numericalControl.PLC_WScadaValue(memIndex, memType, value); } #endregion Write data private int GetMaxCountBetweenLayerComponents(ScadaSchemaLayerModel layer) { // Choose which list contains the maximum number of elements int max = layer.Buttons.Count(); if (layer.Images.Count() > max) max = layer.Images.Count(); if (layer.Inputs.Count() > max) max = layer.Inputs.Count(); if (layer.ProgressBars.Count() > max) max = layer.ProgressBars.Count(); return max; } public CmsError ManageCandies() { CmsError cmsError; int NcCandy = 0; int NCMatr, PCMatr; long NCParam, PCParam; long NCLic, PcPLic; bool bNC_OK, bPC_OK; bool bNC_VALID, bPC_VALID; String strMachNumber = "0"; int machNumber; bool bRewrite, bNcCandy=false, bNewCandy = false; DateTime newDate; //Check if i have to Manage it if(!CandiesController.IsTimeToMangeCandies()) return NO_ERROR; //Read Machine ID cmsError = numericalControl.NC_RMachineNumber(ref strMachNumber); if (cmsError.IsError()) return cmsError; machNumber = Int32.Parse(strMachNumber); //Read Data from NC & elaborate it cmsError = numericalControl.PLC_RCandy(ref NcCandy); if (cmsError.IsError()) return cmsError; bNC_OK = CandiesController.GetDataFromLincense(NcCandy, out NCLic, out NCMatr, out NCParam); bNC_VALID = machNumber == NCMatr && bNC_OK; //Read Data from PC bPC_OK = CandiesController.GetPCLincense(out PcPLic, out PCMatr, out PCParam); bPC_VALID = machNumber == PCMatr && bPC_OK; //Elaborate Licence and write it CandiesController.ElaborateLincense(bPC_VALID, bNC_VALID, PCParam, NCParam, PcPLic, NCLic, out newDate, out bRewrite); if (bRewrite) WriteCandy(newDate, machNumber); //Read Expired Lincense Bit on NC cmsError = numericalControl.PLC_RExpiredCandy(ref bNcCandy); if (cmsError.IsError()) return cmsError; //Manage Expired Lincense Bit if(CandiesController.ElaborateExpiredBit(newDate, bNcCandy, out bNewCandy)) { //Write Expired Lincense Bit on NC cmsError = numericalControl.PLC_WExpiredCandy(bNewCandy); if (cmsError.IsError()) return cmsError; } return NO_ERROR; } public void WriteCandy(DateTime value,int machNumber) { long nDays; int Lic=0; nDays = (value.Ticks / TimeSpan.TicksPerDay); //Imposto nel registro CandiesController.SetPCLincense(machNumber,nDays); //Imposto nel CN Lic = Int32.Parse(CandiesController.SetLincenseFromData(machNumber, nDays)); numericalControl.PLC_WCandy(Lic); } public bool ReadHeadWTime(int Head, out uint hour) { hour = 0; CmsError cmsError = numericalControl.PLC_RWorkedTimeHead(Head, ref hour); if (cmsError.IsError()) return false; return true; } public bool ResetHeadWTime(int Head) { CmsError cmsError = numericalControl.PLC_WResetWorkedTimeHead(Head); if (cmsError.IsError()) return false; return true; } public bool ReadMachineWTime(out uint hour) { hour = 0; CmsError cmsError = numericalControl.PLC_RWorkedTimeMachine(ref hour); if (cmsError.IsError()) return false; return true; } public bool ResetMachineWTime(uint hour) { CmsError cmsError = numericalControl.PLC_WResetWorkedTimeMachine(hour); if (cmsError.IsError()) return false; return true; } //DTOScadaModel scada = new DTOScadaModel //{ // Layers = prodScada.Layers.Select(x => new DTOScadaLayerModel() // { // Id = x.Id, // Buttons = x.Buttons.Select(y => new DTOScadaButtonModel() // { // Id = y.Id // }).ToList(), // Images = x.Images.Select(y => new DTOScadaImageModel() // { // Id = y.Id // }).ToList(), // ProgressBars = x.ProgressBars.Select(y => new DTOScadaProgressBarModel() // { // Id = y.Id // }).ToList(), // Inputs = x.Inputs.Select(y => new DTOScadaInputModel() // { // Id = y.Id // }).ToList() // }).ToList() //}; } }