1733 lines
71 KiB
C#
1733 lines
71 KiB
C#
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 System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using static CMS_CORE_Library.Models.DataStructures;
|
|
using static Step.Config.ServerConfig;
|
|
using static Step.Model.Constants;
|
|
|
|
namespace Step.NC
|
|
{
|
|
public class NcAdapter : IDisposable
|
|
{
|
|
public List<DTOHistoricalArrayModel> HistoricalArray = new List<DTOHistoricalArrayModel>();
|
|
public Nc numericalControl;
|
|
|
|
public NcAdapter() =>
|
|
// 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<DTOAxesModel> axes)
|
|
{
|
|
axes = new List<DTOAxesModel>();
|
|
|
|
// 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<DTOAxisNameModel> axesNames)
|
|
{
|
|
axesNames = new List<DTOAxisNameModel>();
|
|
List<AxisModel> plcAxes = new List<AxisModel>();
|
|
// 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(NcConfig.MachineNumberHasLetters, ref tmpInfo);
|
|
if (cmsError.errorCode != 0)
|
|
return cmsError;
|
|
|
|
if (string.IsNullOrEmpty(tmpInfo))
|
|
tmpInfo = "0000";
|
|
|
|
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.ParseExact(NcConfig.InstallationDate, DATE_FORMATS, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
|
|
// 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;
|
|
|
|
// Get Server version
|
|
genericData.ServerVersion = SupportFunctions.GetSoftwareVersionAndBuildDate();
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
public CmsError GetNcAlarms(out DTOAlarmsModel alarms)
|
|
{
|
|
alarms = new DTOAlarmsModel();
|
|
List<AlarmModel> tmpAlarms = new List<AlarmModel>();
|
|
|
|
// 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<PlcAlarmModel> plcAlarms = new List<PlcAlarmModel>();
|
|
// 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;
|
|
|
|
// Selected process data
|
|
processesData.ActiveOrigin = selectedData.Origin;
|
|
processesData.ActiveOffsetId = selectedData.ActiveOffsetId;
|
|
processesData.ProcessMessage = selectedData.ProcessMessage;
|
|
|
|
// Overrides
|
|
processesData.RapidOverride = selectedData.RapidOverride;
|
|
processesData.WorkOverride = selectedData.WorkOverride;
|
|
|
|
processesData.offsetData = selectedData.OffsetData;
|
|
|
|
// Measure
|
|
processesData.UnitMeasure = UMeas;
|
|
|
|
processesData.FeedOverride = selectedData.FeedOverride;
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
public CmsError GetFunctionsMappedWithNC(out List<DTORuntimeFunctionalityModel> functionsAccessList)
|
|
{
|
|
functionsAccessList = new List<DTORuntimeFunctionalityModel>();
|
|
// Read plc functionality
|
|
List<FunctionalityModel> 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<CounterModel> counters)
|
|
{
|
|
// List of PLC counters
|
|
counters = new List<CounterModel>();
|
|
// 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<DTOMaintenanceModel> maintenance, userId);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
dTOMaintenance = maintenance.Where(x => x.Id == maintenanceId).FirstOrDefault();
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
public CmsError GetMaintenancesWithPermissions(out List<DTOMaintenanceModel> dtoMaintenancesModel, int userId)
|
|
{
|
|
// Return value
|
|
dtoMaintenancesModel = new List<DTOMaintenanceModel>();
|
|
|
|
// Get counters values from PLC
|
|
CmsError cmsError = GetMainenancesCounter(out List<CounterModel> counters);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
using (MaintenancesController maintenancesController = new MaintenancesController())
|
|
{
|
|
// Get the last performed maintenance for each maintenance
|
|
List<PerformedMaintenanceModel> performedMaintenances = maintenancesController.FindLastPerformedMaintenances();
|
|
|
|
// Get all the active maintenances
|
|
List<MaintenanceModel> maintenances = maintenancesController.FindAll(); // TODO db or config file?
|
|
|
|
double percentage = 0;
|
|
TimeSpan missingDays = new TimeSpan();
|
|
CounterModel counter = new CounterModel();
|
|
uint counterValue = 0;
|
|
|
|
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;
|
|
|
|
counterValue = (uint)Math.Ceiling(SupportFunctions.ConvertInUmeas(counterVal, currMaintenance.UnitOfMeasure.Value));
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
if (performed != null && performed.ControlWord == -2)
|
|
{
|
|
performed = null;
|
|
}
|
|
|
|
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 = counterValue,
|
|
OriginalPlcCounter = 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<DTOExpiredMaintenanceModel> expiredMaintenance)
|
|
{
|
|
// Return value
|
|
expiredMaintenance = new List<DTOExpiredMaintenanceModel>();
|
|
|
|
// Get counters values from PLC
|
|
CmsError cmsError = GetMainenancesCounter(out List<CounterModel> counters);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
using (MaintenancesController maintenancesController = new MaintenancesController())
|
|
{
|
|
// Get the last performed maintenance for each maintenance
|
|
List<PerformedMaintenanceModel> performedMaintenances = maintenancesController.FindLastPerformedMaintenances();
|
|
|
|
// Get all the active maintenances
|
|
List<MaintenanceModel> 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<DTOUserSoftKeyModel> softKeys)
|
|
{
|
|
softKeys = new List<DTOUserSoftKeyModel>();
|
|
List<SoftKeysModel> plcSoftKeys = new List<SoftKeysModel>();
|
|
|
|
// 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<DTONcSoftKeyModel> ncSoftKeys)
|
|
{
|
|
ncSoftKeys = new List<DTONcSoftKeyModel>();
|
|
List<SoftKeysModel> plcSoftKeys = new List<SoftKeysModel>();
|
|
|
|
// 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<DTOHeadModel> heads)
|
|
{
|
|
// Returned value
|
|
heads = new List<DTOHeadModel>();
|
|
// Number of configured heads
|
|
int headsNumber = HeadsConfig.Count;
|
|
|
|
List<HeadDataModel> plcHeads = new List<HeadDataModel>();
|
|
// 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.Param3 >= configuredHead.WarningLimit,
|
|
inAlarm = head.Param3 >= configuredHead.AlarmLimit,
|
|
OverrideEditable = head.OverrideEditable,
|
|
ActualSpeed = head.Param1,
|
|
Load = head.Param3,
|
|
MountedTool = (ushort)head.Param2,
|
|
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,
|
|
Disabled = head.Tool.Disabled,
|
|
Measured = head.Tool.Measured,
|
|
Broken = head.Tool.Broken,
|
|
MaxSpeed = (int)head.Tool.MaxSpeed,
|
|
MaxLoad = (byte)head.Tool.MaxLoad,
|
|
ResidualLife = (int)head.Tool.ResidualLife
|
|
}
|
|
});
|
|
}
|
|
break;
|
|
|
|
case HEAD_TYPE.AWJ:
|
|
{
|
|
float vacumValue = (float)head.Param2 / 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.Param1,
|
|
Abrasive = Convert.ToUInt16(head.Param3),
|
|
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.Param1,
|
|
OverrideEditable = head.OverrideEditable,
|
|
Override = head.Override,
|
|
IsActive = head.IsActive,
|
|
IsSelected = head.IsSelected,
|
|
AbrasiveIsActive = head.AbrasiveIsActive,
|
|
WorkedTime = head.WorkedTime
|
|
});
|
|
}
|
|
break;
|
|
|
|
case HEAD_TYPE.ADDITIVE:
|
|
{
|
|
SetValueHistoricalArray(HistoricalArray, head.Param1, (int)head.Id);
|
|
heads.Add(new DTOAdditive()
|
|
{
|
|
Id = head.Id,
|
|
Process = head.Process,
|
|
Type = configuredHead.Type.ToString(),
|
|
inAlarm = false,
|
|
inWarning = false,
|
|
OverrideEditable = head.OverrideEditable,
|
|
Override = head.Override,
|
|
IsActive = head.IsActive,
|
|
IsSelected = head.IsSelected,
|
|
FusionTemperature = head.Param1,
|
|
ExtruderPressure = (ushort)head.Param2,
|
|
NozzlePressure = head.Param3,
|
|
TemperaturesArray = HistoricalArray.Where(h => h.Head == head.Id).ToList(),
|
|
AbrasiveIsActive = true,
|
|
WorkedTime = head.WorkedTime
|
|
});
|
|
}
|
|
break;
|
|
|
|
case HEAD_TYPE.CUTTING_GLASS:
|
|
{
|
|
float pressureValue = (float)head.Param1 / 100;
|
|
heads.Add(new DTOCuttingGlass()
|
|
{
|
|
Id = head.Id,
|
|
Process = head.Process,
|
|
Type = configuredHead.Type.ToString(),
|
|
inAlarm = false,
|
|
inWarning = false,
|
|
ActualPressure = pressureValue,
|
|
OverrideEditable = false,
|
|
Override = 0,
|
|
IsActive = head.IsActive,
|
|
IsSelected = head.IsSelected,
|
|
AbrasiveIsActive = false,
|
|
WorkedTime = head.WorkedTime
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
private void SetValueHistoricalArray(List<DTOHistoricalArrayModel> h, int t, int id)
|
|
{
|
|
if (h.Where(x => x.Head == id).ToList().Count >= 50)
|
|
{
|
|
DTOHistoricalArrayModel idx = h.Where(x => x.Head == id).FirstOrDefault();
|
|
h.Remove(idx);
|
|
}
|
|
|
|
int lastValue = h.Where(x => x.Head == id).LastOrDefault() == null ? -1 : h.Where(x => x.Head == id).LastOrDefault().Value;
|
|
|
|
if (lastValue != t)
|
|
{
|
|
DTOHistoricalArrayModel ha = new DTOHistoricalArrayModel();
|
|
ha.Head = id;
|
|
ha.Value = t;
|
|
ha.TimeStamp = DateTime.Now;
|
|
|
|
h.Add(ha);
|
|
}
|
|
}
|
|
|
|
public CmsError GetM155Data(out List<DTOM155InputModel> data)
|
|
{
|
|
data = new List<DTOM155InputModel>();
|
|
List<M155InputIsNeededModel> ncData = new List<M155InputIsNeededModel>();
|
|
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 GetM156Data(out List<DTOM156InputModel> data)
|
|
{
|
|
data = new List<DTOM156InputModel>();
|
|
List<M156InputIsNeededModel> ncData = new List<M156InputIsNeededModel>();
|
|
CmsError cmsError = numericalControl.PLC_RM156Data(ref ncData);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
if (ncData.Count() > 0)
|
|
{
|
|
foreach (var m156Message in ncData)
|
|
{
|
|
var inp = InputsOperatorConfig.Where(x => m156Message.Id == x.Id).FirstOrDefault();
|
|
|
|
var buttons = inp.Buttons?.ToDictionary(x => x.Key, x => x.Key.ToString());
|
|
if (inp != null)
|
|
{
|
|
data.Add(new DTOM156InputModel()
|
|
{
|
|
Id = inp.Id,
|
|
isM156 = true,
|
|
Buttons = buttons,
|
|
Type = inp.Type,
|
|
Process = m156Message.Process,
|
|
Value = m156Message.Value
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public CmsError GetM157Data(out List<DTOM157DataModel> data)
|
|
{
|
|
data = new List<DTOM157DataModel>();
|
|
List<M157DataModel> ncData = new List<M157DataModel>();
|
|
CmsError cmsError = numericalControl.PLC_RM157Data(ref ncData);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
data = ncData.Select(x => new DTOM157DataModel()
|
|
{
|
|
CountdownIsActive = x.CountdownIsActive,
|
|
Process = x.Process,
|
|
Timer = x.Timer,
|
|
TimerInputNeeded = x.TimerInputNeeded
|
|
}).ToList();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public CmsError GetM154Data(out List<M154DataModel> data, out bool MTCStatus)
|
|
{
|
|
MTCStatus = false;
|
|
data = new List<M154DataModel>();
|
|
|
|
return numericalControl.PLC_RM154Data(ref data, ref MTCStatus);
|
|
}
|
|
|
|
public CmsError WriteM154Ack(int processId)
|
|
{
|
|
return numericalControl.PLC_W154ManageAck(processId);
|
|
}
|
|
|
|
public CmsError ReadScadasData(List<ScadaSchemaModel> schemasToRead, out List<DTOScadaModel> scadas)
|
|
{
|
|
CmsError cmsError = NO_ERROR;
|
|
scadas = new List<DTOScadaModel>();
|
|
|
|
List<int> alreadyReadScada = new List<int>();
|
|
|
|
foreach (var schema in schemasToRead)
|
|
{
|
|
DTOScadaModel scadaValue = new DTOScadaModel();
|
|
// Avoid duplicated reads
|
|
if (!alreadyReadScada.Contains(schema.Id))
|
|
{
|
|
// Read one schema
|
|
cmsError = ReadScadaData(schema, out 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 schema, out DTOScadaModel scadaValue)
|
|
{
|
|
if (NcConfig.NcVendor != NC_VENDOR.SIEMENS)
|
|
{
|
|
// Read OSAI FANUC schema
|
|
CmsError cmsError = ReadNcScada(schema, out scadaValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
else
|
|
{
|
|
// Read SIEMENS schema
|
|
CmsError cmsError = ReadSiemensScadaSiemens(schema, out scadaValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public CmsError ReadNcScada(ScadaSchemaModel scadaSchema, out DTOScadaModel scadaValue)
|
|
{
|
|
//ReadScadaDataSiemens(scadaSchema, out scadaValue);
|
|
|
|
//return NO_ERROR;
|
|
CmsError cmsError = NO_ERROR;
|
|
scadaValue = new DTOScadaModel()
|
|
{
|
|
Id = scadaSchema.Id,
|
|
Name = scadaSchema.Name,
|
|
IsInProductionPage = scadaSchema.IsInProductionPage,
|
|
Buttons = new List<DTOScadaButtonModel>()
|
|
};
|
|
|
|
// 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.Labels.ElementAtOrDefault(i) != null)
|
|
{
|
|
if (layer.Labels[i].MemEnabledIndex != null)
|
|
{
|
|
// Read enabled from PLC
|
|
cmsError = numericalControl.PLC_RScadaValue(layer.Labels[i].MemEnabledIndex, SCADA_MEM_TYPE.BOOL, ref val);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
// Populate & add new object into scada model
|
|
scadaValue.Labels.Add(new DTOScadaLabelModel()
|
|
{
|
|
Id = layer.Labels[i].Id,
|
|
IsVisible = Convert.ToBoolean(val)
|
|
});
|
|
}
|
|
else
|
|
{
|
|
scadaValue.Labels.Add(new DTOScadaLabelModel()
|
|
{
|
|
Id = layer.Labels[i].Id,
|
|
IsVisible = true
|
|
});
|
|
}
|
|
}
|
|
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,
|
|
IsEnabled = 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)
|
|
{
|
|
if (layer.Inputs.ElementAtOrDefault(i) != null && layer.Inputs[i].Status.Action.ToLower() == "read")
|
|
{
|
|
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 = false, //Convert.ToBoolean(val),
|
|
Value = val2
|
|
}
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// 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;
|
|
|
|
// Populate & add new object into scada model
|
|
scadaValue.Inputs.Add(new DTOScadaInputModel()
|
|
{
|
|
Id = layer.Inputs[i].Id,
|
|
Value = new DTOScadaValueModel()
|
|
{
|
|
IsEnabled = Convert.ToBoolean(val), //Convert.ToBoolean(val),
|
|
Value = val2
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return cmsError;
|
|
}
|
|
|
|
public CmsError ReadSiemensScadaSiemens(ScadaSchemaModel scadaSchema, out DTOScadaModel scadaValue)
|
|
{
|
|
List<ScadaObjectModel> inputData = new List<ScadaObjectModel>();
|
|
List<ScadaObjectModel> booleanValue = new List<ScadaObjectModel>();
|
|
CmsError cmsError = NO_ERROR;
|
|
scadaValue = new DTOScadaModel()
|
|
{
|
|
Id = scadaSchema.Id,
|
|
Name = scadaSchema.Name,
|
|
IsInProductionPage = scadaSchema.IsInProductionPage,
|
|
Buttons = new List<DTOScadaButtonModel>()
|
|
};
|
|
|
|
// Cycle inside layers
|
|
foreach (var layer in scadaSchema.Layers)
|
|
{
|
|
object val = 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.Labels.ElementAtOrDefault(i) != null)
|
|
{
|
|
if (layer.Labels[i].MemEnabledIndex != null)
|
|
{
|
|
var label = layer.Labels[i];
|
|
// Add labelVisible to the list of bolean values to be readed
|
|
booleanValue.Add(new ScadaObjectModel()
|
|
{
|
|
Id = label.Id,
|
|
Address = label.MemEnabledIndex,
|
|
MemType = SCADA_MEM_TYPE.BOOL,
|
|
Round = 0,
|
|
Action = SCADA_ACTION.READ,
|
|
ObjectType = (int)SCADA_ELEMENT_TYPE.LABEL
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// if memory index is not declared, automatically the label is visible
|
|
scadaValue.Labels.Add(new DTOScadaLabelModel()
|
|
{
|
|
Id = layer.Labels[i].Id,
|
|
IsVisible = true
|
|
});
|
|
}
|
|
}
|
|
|
|
if (layer.Buttons.ElementAtOrDefault(i) != null)
|
|
{
|
|
var button = layer.Buttons[i];
|
|
// Add buttonEnabled to the list of bolean values to be readed
|
|
booleanValue.Add(new ScadaObjectModel()
|
|
{
|
|
Id = button.Id,
|
|
Address = button.Status.MemEnabledIndex,
|
|
MemType = SCADA_MEM_TYPE.BOOL,
|
|
Round = 0,
|
|
Action = SCADA_ACTION.READ,
|
|
ObjectType = (int)SCADA_ELEMENT_TYPE.BUTTON
|
|
});
|
|
}
|
|
|
|
if (layer.Images.ElementAtOrDefault(i) != null)
|
|
{
|
|
var negate = layer.Images[i].Status.Negate;
|
|
var image = layer.Images[i];
|
|
// Add imageVisible to the list of bolean values to be readed
|
|
booleanValue.Add(new ScadaObjectModel()
|
|
{
|
|
Id = image.Id,
|
|
Address = image.Status.MemVisibleIndex,
|
|
MemType = SCADA_MEM_TYPE.BOOL,
|
|
Round = 0,
|
|
Action = SCADA_ACTION.READ,
|
|
ObjectType = negate ? (int)SCADA_ELEMENT_TYPE.NEGATE_IMAGE : (int)SCADA_ELEMENT_TYPE.IMAGE
|
|
});
|
|
}
|
|
|
|
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)
|
|
{
|
|
var input = layer.Inputs[i];
|
|
SCADA_MEM_TYPE type = SupportFunctions.GetMemTypeFromString(input.Status.Type);
|
|
// InputData list is made up of the values of inputs and the next element of each value is the isVisible field of the same input
|
|
|
|
// Add Value information
|
|
inputData.Add(new ScadaObjectModel()
|
|
{
|
|
Id = input.Id,
|
|
Address = input.Status.MemValueIndex,
|
|
MemType = type,
|
|
Round = input.Status.Round,
|
|
Action = input.Status.Action,
|
|
});
|
|
|
|
// Add is visible to the item to be readed
|
|
inputData.Add(new ScadaObjectModel()
|
|
{
|
|
Id = input.Id,
|
|
Address = input.Status.MemEnabledIndex,
|
|
MemType = SCADA_MEM_TYPE.BOOL,
|
|
Round = input.Status.Round,
|
|
Action = input.Status.Action,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
//Stopwatch st = new Stopwatch();
|
|
//st.Start();
|
|
|
|
// Read input data ( value, isEnabled, value2, isEnabled2 ...)
|
|
cmsError = numericalControl.PLC_RScadaSiemens(ref inputData);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Read bolean values (isVisible, isEnabled, isEnabled ...)
|
|
cmsError = numericalControl.PLC_RScadaSiemens(ref booleanValue);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
for (int i = 0; i < booleanValue.Count() - 1; i++)
|
|
{
|
|
var enabled = booleanValue[i];
|
|
|
|
switch (enabled.ObjectType)
|
|
{
|
|
case (int)SCADA_ELEMENT_TYPE.BUTTON:
|
|
{
|
|
// Populate & add new object into scada model
|
|
scadaValue.Buttons.Add(new DTOScadaButtonModel()
|
|
{
|
|
Id = enabled.Id,
|
|
IsEnabled = Convert.ToBoolean(enabled.Value)
|
|
});
|
|
}
|
|
break;
|
|
case (int)SCADA_ELEMENT_TYPE.IMAGE:
|
|
case (int)SCADA_ELEMENT_TYPE.NEGATE_IMAGE:
|
|
{
|
|
// Populate & add new object into scada model
|
|
scadaValue.Images.Add(new DTOScadaImageModel()
|
|
{
|
|
Id = enabled.Id,
|
|
IsVisible = enabled.ObjectType == (int)SCADA_ELEMENT_TYPE.NEGATE_IMAGE ? !Convert.ToBoolean(enabled.Value) : Convert.ToBoolean(enabled.Value)
|
|
});
|
|
}
|
|
break;
|
|
case (int)SCADA_ELEMENT_TYPE.LABEL:
|
|
{
|
|
// Populate & add new object into scada model
|
|
scadaValue.Labels.Add(new DTOScadaLabelModel()
|
|
{
|
|
Id = enabled.Id,
|
|
IsVisible = Convert.ToBoolean(enabled.Value)
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < inputData.Count() - 1; i += 2)
|
|
{
|
|
var obj = inputData[i];
|
|
var enabled = inputData[i + 1];
|
|
|
|
// Populate & add new object into scada model
|
|
scadaValue.Inputs.Add(new DTOScadaInputModel()
|
|
{
|
|
Id = obj.Id,
|
|
Value = new DTOScadaValueModel()
|
|
{
|
|
IsEnabled = obj.Action.ToLower() == SCADA_ACTION.READ ? false : Convert.ToBoolean(enabled.Value),
|
|
Value = obj.Value
|
|
}
|
|
});
|
|
}
|
|
|
|
//st.Stop();
|
|
//Console.WriteLine(st.ElapsedMilliseconds);
|
|
|
|
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)
|
|
{
|
|
//if(NC_VENDOR.OSAI)
|
|
//// Set to true power on data by id
|
|
//return numericalControl.NC_WLanguage(language);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
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 WriteM156Data(int process, double responseValue)
|
|
{
|
|
return numericalControl.PLC_WM156Response(process, responseValue);
|
|
}
|
|
|
|
public CmsError WriteScada(string memIndex, SCADA_MEM_TYPE memType, object value)
|
|
{
|
|
return numericalControl.PLC_WScadaValue(memIndex, memType, value);
|
|
}
|
|
|
|
public CmsError WriteM157Data(int process, ushort responseValue)
|
|
{
|
|
return numericalControl.PLC_WM157Timer(process, responseValue);
|
|
}
|
|
|
|
#endregion Write data
|
|
|
|
private int GetMaxCountBetweenLayerComponents(ScadaSchemaLayerModel layer)
|
|
{
|
|
// Choose which list contains the maximum number of elements
|
|
int max = layer.Buttons.Count();
|
|
|
|
if (layer.Labels.Count() > max)
|
|
max = layer.Labels.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()
|
|
{
|
|
// Check if i have to Manage it
|
|
if (!CandiesController.IsTimeToMangeCandies())
|
|
return NO_ERROR;
|
|
|
|
// Read Machine ID
|
|
string strMachNumber = "0";
|
|
CmsError cmsError = numericalControl.NC_RMachineNumber(NcConfig.MachineNumberHasLetters, ref strMachNumber);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
SupportFunctions.ConvertStringMachineNumberIntoNumber(strMachNumber, out bool containsLetters, out int machNumber);
|
|
|
|
// Read Data from NC & elaborate it
|
|
long NcCandy = 0;
|
|
cmsError = numericalControl.PLC_RCandy(ref NcCandy);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
bool bNC_OK = CandiesController.GetDataFromLincense(NcCandy, containsLetters, out long NCLic, out int NCMatr, out long NCParam);
|
|
bool bNC_VALID = machNumber == NCMatr && bNC_OK;
|
|
|
|
// Read Data from PC
|
|
bool bPC_OK = CandiesController.GetPCLincense(containsLetters, out long PcPLic, out int PCMatr, out long PCParam);
|
|
bool bPC_VALID = machNumber == PCMatr && bPC_OK;
|
|
|
|
// Elaborate Licence and write it
|
|
CandiesController.ElaborateLincense(bPC_VALID, bNC_VALID, PCParam, NCParam, PcPLic, NCLic, out DateTime newDate, out bool bRewrite);
|
|
if (bRewrite)
|
|
WriteCandy(newDate, machNumber);
|
|
|
|
// Read Expired Lincense Bit on NC
|
|
bool bNcCandy = false;
|
|
cmsError = numericalControl.PLC_RExpiredCandy(ref bNcCandy);
|
|
if (cmsError.IsError())
|
|
return cmsError;
|
|
|
|
// Manage Expired Lincense Bit
|
|
if (CandiesController.ElaborateExpiredBit(newDate, bNcCandy, out bool 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;
|
|
long Lic = 0;
|
|
nDays = (value.Ticks / TimeSpan.TicksPerDay);
|
|
|
|
//Imposto nel registro
|
|
CandiesController.SetPCLincense(machNumber, nDays);
|
|
|
|
//Imposto nel CN
|
|
Lic = long.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;
|
|
}
|
|
|
|
public bool ResetMaintenanceCounter(uint counter)
|
|
{
|
|
CmsError cmsError = numericalControl.PLC_WResetMachineCounters(counter);
|
|
if (cmsError.IsError())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public CmsError GetActiveClient(out int clientId)
|
|
{
|
|
clientId = 0;
|
|
return numericalControl.PLC_RActiveClient(ref clientId);
|
|
}
|
|
}
|
|
} |