Files
cms-core-active/CMS_CORE_Library/S7Net/Nc_S7Net.cs
T
2020-05-15 18:39:21 +02:00

4206 lines
152 KiB
C#

using CMS_CORE_Library.Models;
using S7.Net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml.Linq;
using static CMS_CORE_Library.Models.DataStructures;
using static CMS_CORE_Library.Nc;
using static CMS_CORE_Library.Siemens.MEMORY_ADDRESS;
using static CMS_CORE_Library.ToolConfigurations;
using static CMS_CORE_Library.Utils.Nc_Utils;
namespace CMS_CORE_Library.S7Net
{
public class Nc_S7Net : Nc
{
// Global Constants
private const string NcNotFound = "Missing response";
private const string NcNotFound2 = "networking error";
private const string NcNotFound3 = "Nc not Connected";
#if false
private const int IDMinPLCMessage = 700000;
private const int IDMaxPLCMessage = 799999;
private const int IDMinChannel = 10000;
private const int IDMaxChannel = 19999;
#endif
#if false
// Siemens Path Constants
private const string MAX_CHANNEL_NO_PATH = "/Nck/Configuration/maxnumChannels";
private const string CONF_CHANNEL_NO_PATH = "/Nck/Configuration/numChannels";
private const string NC_TYPE_PATH = "/Nck/Configuration/nckType";
private const string NC_VERSION_PATH = "/Nck/Configuration/nckVersion";
private const string LANGUAGE_PATH = "/Nck/Configuration/anLanguageOnHmi";
private const string SERIAL_NO_PATH = "/Nck/State/hwProductSerialNrL";
private const string NC_TIME_PATH = "/Nck/State/sysTimeBCD";
private const string NC_GENERIC_MODE_PATH = "/Bag/State/opMode";
private const string NC_GENERIC_STATE_PATH = "/Channel/State/chanStatus";
private const string JOG_INCR_PATH = "/Channel/GeometricAxis/actIncrVal";
private const string ADVANCED_JOG_PATH = "/Channel/State/machFunc";
private const string RELATIVE_POS_PATH = "/Channel/GeometricAxis/actToolBasPosEN";
private const string UNIT_OF_MEASURE = "/Nck/Configuration/basicLengthUnit";
private const string ACT_PROG_LINES_PATH = "/Channel/ProgramInfo/actPartProgram";
private const string ACT_PROG_NAME_PATH = "/Channel/ProgramPointer/progName";
#endif
// Global Variables
private static DateTime Last_Static_Read;
private static string Cnc_name;
private static string Cnc_SftVersion;
private static string Cnc_SeriesNum;
private static string Cms_MachNumber;
private static string PlcRirm_SeriesNum;
private static uint ConfChannelNo;
private static string UnitOfMeasure;
// Alarms data
private static Dictionary<int, string> PlcMessages;
#if false
private const string PLC_MESSAGES_FILE_PATH = "C:\\Program Files (x86)\\Siemens\\MotionControl\\oem\\sinumerik\\hmi\\lng\\";
private static readonly string AXES_FILE_PATH = AppDomain.CurrentDomain.BaseDirectory + "\\Config\\axesConfig.xml";
// axis data
private static List<AxisModel> AxesData = new List<AxisModel>();
public static uint MAX_AXES_FOR_PROCESS = 20;
// File paths
public const string BASE_FILE_PATH = "//NC/";
public const string NC_FILE_PATH = "MPF.DIR";
private static DataSvc AxesSvc;
private static DataSvc SelectedProcessSvc;
#endif
private static ushort SelectedProcess = 0;
#if false
private static Dictionary<string, double> MachineAxesPosition = new Dictionary<string, double>();
private static Dictionary<string, double> ToGoAxesPosition = new Dictionary<string, double>();
private static Dictionary<string, double> InterpAxesPosition = new Dictionary<string, double>();
private static Dictionary<string, double> ProgrammedAxisPosition = new Dictionary<string, double>();
#endif
private bool EnableAlarms;
private bool EnableHeaters;
private bool EnableModules;
private bool EnableParameters;
private bool EnableProd;
private bool EnableAxes;
// parametri specifici per THERMO
private static List<RecipeParam> thermoParamList;
// connessione S7
private CpuType tipoCpu = CpuType.S71500;
private short rack = 0;
private short slot = 1;
/// <summary>
/// Oggetto PLC da ri-utilizzare...
/// </summary>
protected Plc currPLC;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region Contructor & global methods
///<summary>
///Instantiate The NC-S7Net Class
///</summary>
///<param name = "IpAddress" > Remote Ip-Address of the Nc</param>
///<param name = "RemotePort" > Remote Port of the Nc</param>
///<param name="ConnectionTimeOut">Send/Recieve timeout connection [mS]</param>
public Nc_S7Net(string IpAddress, ushort RemotePort, ushort ConnectionTimeOut)
{
//Setup options
this.EnableAlarms = true;
this.EnableHeaters = true;
this.EnableModules = true;
this.EnableParameters = true;
this.EnableProd = true;
this.EnableAxes = false;
// Setup parametri
Ip = IpAddress;
Port = RemotePort;
// mesasggi generici PLC
PlcMessages = new Dictionary<int, string>();
thermoParamList = new List<RecipeParam>();
}
/// <summary>
/// Instantiate The NC-Siemens Class
/// </summary>
///<param name = "IpAddress" > Remote Ip-Address of the Nc</param>
///<param name = "RemotePort" > Remote Port of the Nc</param>
/// <param name="ConnectionTimeOut">Send/Recieve timeout connection [mS]</param>
/// <param name="EnableAxes">Enable Axes Svc</param>
/// <param name="EnableAlarms">Enable Alarms Svc</param>
/// <param name="EnableHeaters">Enable Heaters Svc</param>
/// <param name="EnableModules">Enable Modules Svc</param>
/// <param name="EnableParameters">Enable Parameters Svc</param>
/// <param name="EnableProd">Enable Prod Svc</param>
public Nc_S7Net(string IpAddress, ushort RemotePort, ushort ConnectionTimeOut, bool EnableAxes, bool EnableAlarms, bool EnableHeaters, bool EnableModules, bool EnableParameters, bool EnableProd)
{
//Setup options
this.EnableAlarms = EnableAlarms;
this.EnableAxes = EnableAxes;
this.EnableHeaters = EnableHeaters;
this.EnableModules = EnableModules;
this.EnableParameters = EnableParameters;
this.EnableProd = EnableProd;
// Setup parametri
Ip = IpAddress;
Port = RemotePort;
// mesasggi generici PLC
PlcMessages = new Dictionary<int, string>();
thermoParamList = new List<RecipeParam>();
}
public override CmsError NC_Connect()
{
// Try to get information
try
{
// Check if Siemens Environment is started
CmsError cmsError = CheckS7Ping();
if (cmsError.IsError())
return cmsError;
// Check connection
currPLC = new Plc(tipoCpu, this.Ip, this.rack, this.slot);
currPLC.Open();
if (currPLC.IsConnected)
Connected = true;
#if false
// InitializeSiemens objects
if (this.EnableAxes)
{
if (AxesSvc == null)
AxesSvc = new DataSvc();
}
#endif
// Setup the alarms (with DB bitmap) --> PlcMessages
if (this.EnableAlarms)
{
// PlcMessages
#if false
SiemensAlarms = new Alarm[] { };
SiemensAlmSvc = new AlarmSvc(ConvertToSTEPLanguage(SiemensLanguage).ThreeLetterISOLanguageName);
SiemensAlmSvc.Subscribe(AlarmsChanged);
Infrastructure.SubscribeLanguageChanged(NcLanguageChanged);
#endif
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
}
#if false
private void ManageSelectedProcess(Guid guid, Item[] item, DataSvcStatus[] status)
{
SelectedProcess = 0;
// Set selectedProcess
for (int i = 0; i < item.Count(); i++)
{
if (status[i].Ok)
{
if (Convert.ToBoolean(item[i].Value))
SelectedProcess = (ushort)(i + 1);
}
}
if (this.EnableAxes)
{
// Clean listener
AxesSvc.UnSubscribe(ManageAxes);
if (SelectedProcess > 0)
{
List<AxisModel> axesConf = new List<AxisModel>();
AXES_RAxesNames(SelectedProcess, ref AxesData);
List<Item> axesData = new List<Item>();
foreach (var conf in AxesData)
{
// Setup the items to be subscribed
// Machine
axesData.Add(new Item() { Path = string.Format("/Nck/{0}[u{1},{2}]", "MachineAxis/actToolBasePos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
// Programmed
axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/cmdProgPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
// Interp
axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/actToolEdgeCenterPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
// Dist to go
axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "MachineAxis/toolBaseDistToGo", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
}
if (axesData.Count() > 0)
// Subscribe to axis changes
AxesSvc.Subscribe(ManageAxes, axesData.ToArray());
}
}
}
private void ManageAxes(Guid guid, Item[] item, DataSvcStatus[] status)
{
lock (MachineAxesPosition)
{
lock (ProgrammedAxisPosition)
{
lock (InterpAxesPosition)
{
lock (ToGoAxesPosition)
{
MachineAxesPosition.Clear();
ProgrammedAxisPosition.Clear();
InterpAxesPosition.Clear();
ToGoAxesPosition.Clear();
for (int i = 0; i < AxesData.Count(); i++)
{
if (status[i * 4].Ok)
MachineAxesPosition.Add(item[i * 4].SymbolicName, Convert.ToDouble(item[i * 4].Value));
if (status[i * 4 + 1].Ok)
ProgrammedAxisPosition.Add(item[i * 4 + 1].SymbolicName, Convert.ToDouble(item[i * 4 + 1].Value));
if (status[i * 4 + 2].Ok)
InterpAxesPosition.Add(item[i * 4 + 2].SymbolicName, Convert.ToDouble(item[i * 4 + 2].Value));
if (status[i * 4 + 3].Ok)
ToGoAxesPosition.Add(item[i * 4 + 3].SymbolicName, Convert.ToDouble(item[i * 4 + 3].Value));
}
}
}
}
}
}
#endif
// Disconnect Method
public override CmsError NC_Disconnect()
{
// Set Connected to FALSE and close the sessions
Connected = false;
currPLC.Close();
return NO_ERROR;
}
#if false
private void SetupToolTableData()
{
DataSvc dataSvc = new DataSvc();
// Read max tool number
Item itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_TOOL");
dataSvc.Read(itemToRead);
MAX_TOOL_NUMER = (int)itemToRead.Value;
// Read max edge per tool number
itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_MAX_CUTTING_EDGE_PERTOOL");
dataSvc.Read(itemToRead);
MAX_EDGES_PER_TOOL = (int)itemToRead.Value;
// Read max tools per family
itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MAXNUM_REPLACEMENT_TOOLS");
dataSvc.Read(itemToRead);
MAX_TOOLS_PER_FAMILY = (int)itemToRead.Value;
// Read max multitools number
itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_MULTITOOL");
dataSvc.Read(itemToRead);
MAX_MULTITOOLS_NUMBER = (int)itemToRead.Value;
// Read max tools per multitools
itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MAX_TOOLS_PER_MULTITOOL");
dataSvc.Read(itemToRead);
MAX_TOOLS_PER_MULTITOOL = (int)itemToRead.Value;
// Read file
string[] toolsStrings = ReadToolTableFile();
// Read max multitools locations
itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_NUM_MULTITOOL_LOCATIONS");
dataSvc.Read(itemToRead);
MAX_MULTITOOLS_LOCATIONS = (int)itemToRead.Value;
// Read Life option
//itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MN_MM_TOOL_MANAGEMENT_MASK");
//LIFE_OPTION_ACTIVE = GetBitValue(Convert.ToInt32(itemToRead.Value), 6);
// MULTITOOL_OPTION_ACTIVE = GetBitValue(Convert.ToInt32(itemToRead.Value), 10);
MULTITOOL_OPTION_ACTIVE = false;
// Read Life option
itemToRead = new Item("/NC/_N_NC_TEA_ACX/$MNS_ACCESS_WRITE_TM_SUPVIS");
dataSvc.Read(itemToRead);
LIFE_OPTION_ACTIVE = Convert.ToInt32(itemToRead.Value) == 7;
// If not active remove fields from config
if (!LIFE_OPTION_ACTIVE)
RemoveLifeParamsFromConfig();
// Read file
PopulateToolsTableFromFileStrings(toolsStrings);
Array.Clear(toolsStrings, 0, toolsStrings.Count());
//// Subscribe to multitools number
//DataSvc d = new DataSvc();
//Item i = new Item() { Path = "/Tool/MTCatalogue/numMultiTools[u1]" };
//d.Subscribe(MultitoolsNumber_OnChange, i);
}
private void SetupMagazinePositionListener()
{
// Setup magazine positions listener
List<Item> magPosItems = new List<Item>();
foreach (var position in MagazinePositionsData)
{
int paramId = ((position.PositionId - 1) * 11) + 5;
magPosItems.Add(new Item()
{
Path = string.Format("/Tool/Magazine/placeData[c{0} , {1}]", position.MagazineId, paramId),
SymbolicName = position.MagazineId + "_" + position.PositionId
});
}
if (magPosItems.Count > 0)
// Subscribe
MagazinePositionSvc.Subscribe(MagazinePositionEnabled_OnChange, magPosItems.ToArray());
}
private void SetupMagazineActionListener()
{
Item magActionsItem = new Item() { Path = MAGAZINE_ACTION_PATH };
// Setup magazine actions listener
MagazineActionsSvc.Subscribe(MagazineAction_OnChange, magActionsItem);
}
#endif
private void RemoveLifeParamsFromConfig()
{
#if false
SiemensToolFieldsConfig.RemoveAll(x => x.Category == "life");
SiemensEdgesFieldsConfiguration.EdgeConfiguration.RemoveAll(x => x.Category == "life");
#endif
}
public override CmsError NC_GetTranslatedPlcMessages(string language, ref Dictionary<int, string> messages)
{
#if false
string filePath;
try
{
PlcMessages = new Dictionary<int, string>();
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(language);
string langName = "";
if (cultureInfo.IsNeutralCulture)
langName = cultureInfo.EnglishName;
else
langName = cultureInfo.Parent.EnglishName;
//Setup the Path
filePath = PLC_MESSAGE_PATH + @"Messaggi_" + langName + @".txt";
//Read From Files
messages = File.ReadAllLines(filePath, Encoding.Default)
.Select(line => line.Split(','))
.Where(line => line.Count() == 2)
.ToDictionary(line => Convert.ToInt32(line[0]), line => line[1].Trim());
return NO_ERROR;
}
catch (Exception ex)
{
return ManageException(ex);
}
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError NC_GetAvailableLanguages(ref ICollection<CultureInfo> languages)
{
#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);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
#endregion Contructor & global methods
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region High level methods
// Get the processes-count configurated
public override CmsError NC_RProcessesNum(ref ushort ProcNumber)
{
CmsError cmsError = ReadStaticNCData();
if (cmsError.IsError())
return cmsError;
ProcNumber = (ushort)ConfChannelNo;
return NO_ERROR;
}
// Get the NC model Name
public override CmsError NC_RModelName(ref string ModelName)
{
CmsError cmsError = ReadStaticNCData();
if (cmsError.IsError())
return cmsError;
ModelName = Cnc_name;
return NO_ERROR;
}
// Get the NC Software Version
public override CmsError NC_RSoftwareVersion(ref string SWV)
{
CmsError cmsError = ReadStaticNCData();
if (cmsError.IsError())
return cmsError;
SWV = Cnc_SftVersion;
return NO_ERROR;
}
// Get the NC Language
public override CmsError NC_RLanguage(ref CultureInfo Language)
{
return FUNCTION_NOT_ALLOWED_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 cmsError = ReadStaticNCData();
if (cmsError.IsError())
return cmsError;
serialNumber = Cnc_SeriesNum;
return NO_ERROR;
}
// Get CMS Machine number
public override CmsError NC_RMachineNumber(bool hasLetters, ref string MachNumber)
{
if (!hasLetters)
{
CmsError cmsError = ReadStaticNCData();
if (cmsError.IsError())
return cmsError;
MachNumber = Cms_MachNumber;
}
else
{
// New method to read machine number
List<byte> lists = new List<byte>();
CmsError cmsError = MEM_RWByteList(R, 0, NEW_MATR_MACC.MemType, NEW_MATR_MACC.Address, NEW_MATR_MACC.SubAddress, 0, 4, ref lists);
if (cmsError.IsError())
return cmsError;
lists.Reverse();
MachNumber = Encoding.ASCII.GetString(lists.ToArray());
}
return NO_ERROR;
}
// Get the Date-Time of the NC
public override CmsError NC_RDateTime(ref DateTime ActualTime)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
// Check if the NC is in running state
public override CmsError NC_RIsRunning(ref bool running)
{
ushort nProcess = 0;
// Get the number of processes
CmsError cmsError = NC_RProcessesNum(ref nProcess);
if (cmsError.IsError())
return cmsError;
ushort i = 1;
running = false;
do
{
PROC_STATUS procStatus = PROC_STATUS.IDLE;
// Read process status
cmsError = PROC_RStatus(i, ref procStatus);
if (cmsError.IsError())
return cmsError;
if (procStatus == PROC_STATUS.RUN)
running = true;
i++;
} while (!running || i <= nProcess);
return NO_ERROR;
}
// Get NC unit of measure
public override CmsError NC_RUnitOfMeasure(ref string unitOfMeasure)
{
CmsError cmsError = ReadStaticNCData();
if (cmsError.IsError())
return cmsError;
unitOfMeasure = UnitOfMeasure;
return NO_ERROR;
}
// Get the Nc Active Alarms
public override CmsError NC_RActiveAlarms(ref List<AlarmModel> alarms)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
// Set the Nc Active Page of the NC
public override CmsError NC_SetScreenVisible(SCREEN_PAGE screen)
{
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()
{
bool plcWatchdog = false;
CmsError cmsError = MEM_RWBoolean(R, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog);
if (cmsError.IsError())
return cmsError;
if (plcWatchdog)
return PLC_NOT_RUNNING_ERROR;
plcWatchdog = true;
return MEM_RWBoolean(W, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog);
}
public override CmsError PLC_RActiveMessages(ref List<PlcAlarmModel> alarms)
{
bool[] statusBits;
int i = 0;
List<int> readValues = new List<int>();
CmsError cmsError;
try
{
alarms.Clear();
// Read on data from memory
cmsError = MEM_RWIntegerList(R, 0,
ALARMS_STATUS.MemType,
ALARMS_STATUS.Address,
ALARMS_STATUS.SubAddress,
(ALARMS_STATUS.Size / 4) + (ALARMS_DATA.Size / 2), // statys_bytes / 4 + data_word / 2
ref readValues);
if (cmsError.IsError())
return cmsError;
alarms.Clear();
//List<int> readValues = new List<int>();
//// Read on data from memory
//CmsError cmsError = MEM_RWIntegerList(R, 0,
// ALARMS_STATUS.MemType,
// ALARMS_STATUS.Address,
// ALARMS_STATUS.SubAddress,
// (ALARMS_STATUS.Size + ALARMS_DATA.Size) / 4, // byte / 4
// ref readValues);
//if (cmsError.IsError())
// return cmsError;
// Convert integer array into bit array
statusBits = IntToBits(readValues.ToArray());
for (i = 0; i < ALARMS_STATUS.Size * 8; i++)
{
// If alarm is active
if (statusBits[i])
{
// Calculate matching alarm byte info address
int dataByteAddress = (i * 16) + ALARMS_NUMBER;
var processList = new List<int>();
// Get processes on which alarm is active
for (int j = dataByteAddress; j < dataByteAddress + 6; j++)
{
if (statusBits[j])
processList.Add(j + 1 - dataByteAddress);
}
// Add alarm info into active alarms list
alarms.Add(new PlcAlarmModel()
{
Id = (uint)i + 1,
IsWarning = statusBits[dataByteAddress + 7],
RestorationIsActive = statusBits[dataByteAddress + 6],
Process = processList
});
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
}
public override CmsError PLC_WRestoreMessage(uint id)
{
// Check id range
if (id > ALARMS_NUMBER)
return INCORRECT_PARAMETERS_ERROR;
// Call restore message
CmsError cmsError = PLC_WStrobe(ALARM_ACK, ALARM_RESTORATION_STROBE, id);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_WRefreshMessage(uint id)
{
// Check id range
if (id > ALARMS_NUMBER)
return INCORRECT_PARAMETERS_ERROR;
// Call restore message
CmsError cmsError = PLC_WStrobe(ALARM_ACK, ALARM_REFRESH_STROBE, id);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_WRefreshAllMessages()
{
return PLC_WNcSoftKey(REFRESH_ALL_ALARMS_SFKEY_INDEX);
}
public override CmsError PLC_RPowerOnData(ref PreAndPostPowerOnModel powerOnModel)
{
int readValue = 0;
// Read pre power on and post power on data from memory
CmsError cmsError = MEM_RWInteger(R, 0, PRE_POST_POWER_ON.MemType, PRE_POST_POWER_ON.Address, PRE_POST_POWER_ON.SubAddress, ref readValue);
if (cmsError.IsError())
return cmsError;
bool[] bits = new bool[32];
// Convert int into to true/false array
bits = IntToBits(readValue);
// Create adn set pre power on object
PrePowerOnModel prePowerOn = new PrePowerOnModel()
{
PowerOn = new PowerOnDataModel() { Id = 1, Active = bits[0], Clickable = bits[16] }, // id = N, bits = N, Clickable = N + 8 (Second bit)
AirPressure = new PowerOnDataModel() { Id = 2, Active = bits[1], Clickable = bits[17] },
ProtectionStatus = new PowerOnDataModel() { Id = 3, Active = bits[2], Clickable = bits[18] },
EmergencyButtons = new PowerOnDataModel() { Id = 4, Active = bits[3], Clickable = bits[19] },
SettingMode = new PowerOnDataModel() { Id = 5, Active = bits[4], Clickable = bits[20] },
StartingKey = new PowerOnDataModel() { Id = 6, Active = bits[5], Clickable = bits[21] }
};
// Create and set post power on object
PostPowerOnModel postPowerOn = new PostPowerOnModel()
{
AxisReset = new PowerOnDataModel() { Id = 9, Active = bits[8], Clickable = bits[24] }, // id = N - 8, bits = N, Clickable = N + 8 (Second bit)
WaterjetPump = new PowerOnDataModel() { Id = 10, Active = bits[9], Clickable = bits[25] }
};
powerOnModel = new PreAndPostPowerOnModel()
{
PostPowerOn = postPowerOn,
PrePowerOn = prePowerOn
};
return NO_ERROR;
}
public override CmsError PLC_WPowerOnData(uint id, bool value)
{
// Check bit range
if (id > 16)
return INCORRECT_PARAMETERS_ERROR;
// Call restore message
CmsError cmsError = PLC_WStrobe(PRE_POST_POWER_ON_ACK, PRE_POST_POWER_ON_CLICKED, id);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_RFunctionAccess(ref List<FunctionalityModel> functions)
{
List<int> readValues = new List<int>();
int numberOfIntegers = FUNCTION_ACCESS.Size / 4;
// Read functions access data from memory
CmsError cmsError = MEM_RWIntegerList(R, 0, FUNCTION_ACCESS.MemType, FUNCTION_ACCESS.Address, FUNCTION_ACCESS.SubAddress, numberOfIntegers, ref readValues);
if (cmsError.IsError())
return cmsError;
functions = new List<FunctionalityModel>();
// Convert int into to true/false array
bool[] bits = IntToBits(readValues.ToArray());
// Convert array into structured data
for (int i = 0; i < bits.Count(); i++)
{
functions.Add(new FunctionalityModel()
{
Id = (uint)i + 1,
IsActive = bits[i]
});
}
return NO_ERROR;
}
public override CmsError PLC_RAxesResetData(ref AxisResetDataModel axisResetData)
{
byte value = 0;
// Read byte from memory
CmsError cmsError = MEM_RWByte(R, 0, AXIS_RESET_PROCEDURE.MemType, AXIS_RESET_PROCEDURE.Address, AXIS_RESET_PROCEDURE.SubAddress, 0, ref value);
if (cmsError.IsError())
return cmsError;
// Check last bit if is active
if ((value & 128) == 128)
{
// Set to 0 last bit( isActive bit x - 128 )
// From 0 to 6 bit represents percentage
// If higher than 100 then value = 100
byte percentage = value - 128 > 100 ? (byte)100 : (byte)(value - 128);
axisResetData = new AxisResetDataModel()
{
IsActive = true,
Percentage = percentage
};
}
return NO_ERROR;
}
public override CmsError PLC_RNcSoftKeys(ref List<SoftKeysModel> ncSoftKeys)
{
CmsError cmsError = PLC_RSoftKeys(NC_SOFTKEYS_VALUE, NC_SOFTKEYS_CLICKABLE, ref ncSoftKeys);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_RUserSoftKeys(ref List<SoftKeysModel> softKeys)
{
CmsError cmsError = PLC_RSoftKeys(USER_SOFTKEYS_VALUE, USER_SOFTKEYS_CLICKABLE, ref softKeys);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
private CmsError PLC_RSoftKeys(MEMORY_CELL softKeyStatusMemory, MEMORY_CELL softKeysClickableMemory, ref List<SoftKeysModel> softKeys)
{
softKeys = new List<SoftKeysModel>();
List<int> readValues = new List<int>();
int memorySizeToRead = (softKeyStatusMemory.Size + softKeysClickableMemory.Size);
// Offset between status and clickable data
int offset = softKeyStatusMemory.Size * 8;
// Read on data from memory
CmsError cmsError = MEM_RWIntegerList(R, 0,
softKeyStatusMemory.MemType,
softKeyStatusMemory.Address,
softKeyStatusMemory.SubAddress,
memorySizeToRead / 4,
ref readValues);
if (cmsError.IsError())
return cmsError;
// Convert ints into an array of bools
bool[] bits = IntToBits(readValues.ToArray());
// Convert array into structured data
for (ushort i = 0; i < bits.Count() / 2; i++)
{
softKeys.Add(new SoftKeysModel()
{
Id = (uint)i + 1,
Value = bits[i],
Active = bits[i + offset]
});
}
return NO_ERROR;
}
public override CmsError PLC_WNcSoftKey(uint id)
{
// Check id range
if (id > NC_SOFTKEYS_NUMBER)
return INCORRECT_PARAMETERS_ERROR;
// Write strobe into memory
CmsError cmsError = PLC_WStrobe(NC_SOFT_KEYS_ACK, NC_SOFT_KEYS_CLICKED, id);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_WUserSoftKey(uint id)
{
// Check id range
if (id > USER_SOFTKEYS_NUMBER)
return INCORRECT_PARAMETERS_ERROR;
// Write strobe into memory
CmsError cmsError = PLC_WStrobe(USER_SOFT_KEYS_ACK, USER_SOFT_KEYS_CLICKED, id);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_RHeadsData(List<HeadDataModel> heads, int number)
{
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 cmsError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_WResetWorkedTimeMachine(uint time)
{
uint actTime = 0;
// Read actual Value
CmsError cmsError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref actTime);
if (cmsError.IsError())
return cmsError;
// Per richiedere l'azzeramento del timer invio 4 volte il segnale velocemente al PLC
// Il PLC resetta il bit e aspetta quello successivo entro 500ms, se no abortisce
// Sfrutto così la velocità dei sw, cosa che un "nemico" a mano se provasse a forzare il bit non avrebbe
bool bitValue = true;
int nTry = 0;
for (int i = 0; i <= 4; i++)
{
//Scrivo il bit
bitValue = true;
nTry = 0;
cmsError = MEM_RWBoolean(W, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
if (cmsError.IsError())
return cmsError;
//Aspetto che venga abbassato
do
{
Thread.Sleep(50);
nTry += 1;
cmsError = MEM_RWBoolean(R, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
if (cmsError.IsError())
return cmsError;
} while (bitValue && nTry <= 10);
//se il valore è rimasto a 1 il plc non l'ha preso in carico, e abortisco
if (bitValue)
{
bitValue = true;
cmsError = MEM_RWBoolean(W, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
if (cmsError.IsError())
return cmsError;
return PLC_NOT_RUNNING_ERROR;
}
else
{
//Se l'ha abbassato scrivo il nuovo dato
cmsError = MEM_RWDWord(W, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time);
}
}
return NO_ERROR;
}
public override CmsError PLC_WHeadOverride(uint id, HEAD_OVERRIDE_SIGN sign)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
// MACHINE COUNTERS
public override CmsError PLC_RMachineCounters(ref List<CounterModel> counters)
{
List<uint> val = new List<uint>();
// Read ints
CmsError cmsError = MEM_RWDWordList(R, 0, COUNTERS_DATA.MemType, COUNTERS_DATA.Address, COUNTERS_DATA.SubAddress, COUNTERS_DATA.Size / 4, ref val);
if (cmsError.IsError())
return cmsError;
// Set return value
uint i = 0;
counters = val.Select(x => new CounterModel()
{
Id = i++,
Value = x
})
.ToList();
return NO_ERROR;
}
public override CmsError PLC_WResetMachineCounters(uint counter)
{
bool isResettable = false;
CmsError cmsError = MEM_RWBoolean(R, 0, COUNTER_IS_RESETTABLE.MemType, COUNTER_IS_RESETTABLE.Address, COUNTER_IS_RESETTABLE.SubAddress, (int)(counter - 1), ref isResettable);
if (cmsError.IsError())
return cmsError;
if (!isResettable)
return FUNCTION_NOT_ALLOWED_ERROR;
cmsError = PLC_WStrobe(COUNTER_IS_RESETTABLE_ACK, COUNTER_IS_RESETTABLE_STROBE, counter);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_ROperatorInputIsNeeded(ref List<M155InputIsNeededModel> 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<M154DataModel> data, ref bool MTCOnOff)
{
MTCOnOff = false;
CmsError cmsError = MEM_RWBoolean(R, 0, M154_SWITCH_ONOFF.MemType, M154_SWITCH_ONOFF.Address, M154_SWITCH_ONOFF.SubAddress, 1, ref MTCOnOff);
if (cmsError.IsError())
return cmsError;
byte val = 0;
cmsError = MEM_RWByte(R, 0, M154_STROBE.MemType, M154_STROBE.Address, M154_STROBE.SubAddress, 0, ref val);
if (cmsError.IsError())
return cmsError;
// Convert a byte to an array of booleans
bool[] bits = ByteToBits(val);
string[] parameters;
string tmpStr = "";
for (uint processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
{
if (bits[processId - 1])
{
// Read active program line
cmsError = PROC_ReadActiveLine(processId, ref tmpStr);
if (cmsError.IsError())
return cmsError;
// Parse parameters
parameters = ExtractM154ParametersFromNcCodeLine(tmpStr);
data.Add(new M154DataModel()
{
Process = processId,
IsNeeded = bits[processId - 1],
Parameters = parameters
});
}
}
return NO_ERROR;
}
public override CmsError PLC_W154ManageAck(int processId)
{
return PLC_ManageActiveAck(M154_STROBE.Address, M154_STROBE.SubAddress, processId - 1, M154_ACK.Address, M154_ACK.SubAddress, processId - 1, M154_STROBE.MemType);
}
public override CmsError PLC_RM156Data(ref List<M156InputIsNeededModel> value)
{
byte val = 0;
List<byte> vals = new List<byte>();
CmsError cmsError = MEM_RWByte(R, 0, M156_INPUT_NEEDED.MemType, M156_INPUT_NEEDED.Address, M156_INPUT_NEEDED.SubAddress, 0, ref val);
if (cmsError.IsError())
return cmsError;
cmsError = MEM_RWByteList(R, 0, M156_INPUT_ID_LIST.MemType, M156_INPUT_ID_LIST.Address, 0, M156_INPUT_ID_LIST.Size, ref vals);
if (cmsError.IsError())
return cmsError;
bool[] bits = ByteToBits(val);
for (int processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
{
if (bits[processId - 1])
{
#if false
Item item = new Item()
{
Path = string.Format("/channel/parameter/r[c{0} , 154]", processId),
};
try
{
DataSvc dataSvc = new DataSvc();
dataSvc.Read(item);
}
catch (Exception ex)
{
return ManageException(ex);
}
// Parse line & get parameters
value.Add(new M156InputIsNeededModel()
{
Process = (uint)processId,
Id = vals.ElementAt(processId - 1),
Value = Convert.ToDouble(item.Value)
});
#endif
}
}
return NO_ERROR;
}
public override CmsError PLC_WM156Response(int process, double responseVal)
{
//CmsError cmsError = MEM_RWDouble(W, 0, MEMORY_TYPE.Osai_GD, 900 + (process - 1), ref responseVal);
//if (cmsError.IsError())
// return cmsError;
return PLC_WStrobe(M156_INPUT_ACK, M156_INPUT_STROBE, (uint)process);
}
public override CmsError PLC_RScadaValue(string memIndex, SCADA_MEM_TYPE memType, ref object value)
{
if (memType == SCADA_MEM_TYPE.BOOL)
{
if (memIndex.ToUpper() == "FALSE")
{
value = false;
return NO_ERROR;
}
else if (memIndex.ToUpper() == "TRUE")
{
value = true;
return NO_ERROR;
}
}
string[] index = memIndex.Split('.');
CmsError cmsError = NO_ERROR;
try
{
if (index.Count() == 0 || index.Count() == 1)
return INCORRECT_PARAMETERS_ERROR;
else if (index.Count() == 2)
{
if (memType == SCADA_MEM_TYPE.INT)
{
// read INT
int val = 0;
cmsError = MEM_RWInteger(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
value = val;
}
else if (memType == SCADA_MEM_TYPE.WORD)
{ // read WORD
short val = 0;
cmsError = MEM_RWShort(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
value = val;
}
else if (memType == SCADA_MEM_TYPE.REAL)
{ // read DOUBLE
double val = 0;
cmsError = MEM_RWDouble(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
value = val;
}
else
{ // read BYTE
byte val = 0;
cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), 0, ref val);
value = val;
}
}
else if (index.Count() == 3 && memType == SCADA_MEM_TYPE.BOOL)
{ // read BOOL
bool val = false;
cmsError = MEM_RWBoolean(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val);
value = val;
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return cmsError;
}
public override CmsError PLC_RScadaSiemens(ref List<ScadaObjectModel> objects)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
try
{
List<Item> items = new List<Item>();
string bit,
address;
char charType = 'B';
// Cycle through object
for (int i = 0; i < objects.Count(); i++)
{
// Split memory string -> X.Y.Z
string[] splittedMem = objects[i].Address.Split('.');
bit = "0";
address = "0";
bool read = true;
switch (objects[i].MemType)
{
case SCADA_MEM_TYPE.BOOL:
{
// Check if memory contains default value
if (splittedMem[0].ToUpper() == "FALSE")
{
objects[i].Value = false;
read = false;
break;
}
else if (splittedMem[0].ToUpper() == "TRUE")
{
objects[i].Value = true;
read = false;
break;
}
bit = splittedMem[2];
address = splittedMem[1];
charType = 'X'; // Siemens memory type character
}
break;
case SCADA_MEM_TYPE.BYTE:
{
address = splittedMem[1];
charType = 'B';
}
break;
case SCADA_MEM_TYPE.INT:
{
address = splittedMem[1];
charType = 'D';
}
break;
case SCADA_MEM_TYPE.WORD:
{
address = splittedMem[1];
charType = 'W';
}
break;
case SCADA_MEM_TYPE.REAL:
{
address = splittedMem[1];
charType = 'D';
}
break;
}
// If needs to read
if (read)
{
// Convert splitted address into Siemens address
ConvertMemToPath(MEMORY_TYPE.Siemens_DB,
Convert.ToInt32(splittedMem[0]),
Convert.ToInt32(address),
Convert.ToInt32(bit),
1,
charType,
out string item);
// Add to the list of items to be readed
items.Add(new Item()
{
Path = item
});
}
}
if (items.Count() > 0)
{
// Read data
DataSvc dataSvc = new DataSvc();
dataSvc.Read(items.ToArray());
int alreadyReaded = 0;
for (int i = 0; i < objects.Count(); i++)
{
// Skip the objects already valorised
if (objects[i].Value == null)
{
switch (objects[i].MemType)
{
case SCADA_MEM_TYPE.BOOL:
{
// Valorize data
objects[i].Value = Convert.ToBoolean(items[i - alreadyReaded].Value);
}
break;
case SCADA_MEM_TYPE.BYTE:
{
objects[i].Value = Convert.ToByte(items[i - alreadyReaded].Value);
}
break;
case SCADA_MEM_TYPE.INT:
{
objects[i].Value = Convert.ToInt32(items[i - alreadyReaded].Value);
}
break;
case SCADA_MEM_TYPE.WORD:
{
objects[i].Value = Convert.ToInt16(items[i - alreadyReaded].Value);
}
break;
case SCADA_MEM_TYPE.REAL:
{
// Convert value to double
var byteVal = BitConverter.GetBytes((uint)items[i - alreadyReaded].Value);
var value = unchecked(Convert.ToDouble(BitConverter.ToSingle(byteVal, 0)));
objects[i].Value = Math.Round(value, objects[i].Round);
}
break;
}
}
else
{
// Count items already readed
alreadyReaded++;
}
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value)
{
string[] index = memIndex.Split('.');
CmsError cmsError = NO_ERROR;
if (index.Count() == 0)
return INCORRECT_PARAMETERS_ERROR;
else if (index.Count() == 2)
{
if (memType == SCADA_MEM_TYPE.INT)
{
// write INT
int val = Convert.ToInt32(value);
cmsError = MEM_RWInteger(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
}
else if (memType == SCADA_MEM_TYPE.WORD)
{ // write WORD
short val = Convert.ToInt16(value);
cmsError = MEM_RWShort(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
}
else if (memType == SCADA_MEM_TYPE.REAL)
{ // write DOUBLE
double val = Convert.ToDouble(value);
cmsError = MEM_RWDouble(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
}
else
{ // write byte
byte val = Convert.ToByte(value);
cmsError = MEM_RWByte(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), 0, ref val);
}
}
else if (index.Count() == 3 && memType == SCADA_MEM_TYPE.BOOL)
{ // write BOOL
bool val = Convert.ToBoolean(value);
cmsError = MEM_RWBoolean(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val);
}
return cmsError;
}
public override CmsError PLC_WAssistedToolingCmd(ushort toolId, ushort familyId, ushort shankId, ushort magazineId, ushort positionId, ASSISTED_TOOLING_ACTION action)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError PLC_RAssistedToolingData(ref AssistedToolingModel data)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError PLC_WTerminateAssistedToolingProcedure()
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
private CmsError PLC_WStrobe(MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id)
{
CmsError cmsError;
bool readValue = false;
bool writeValue = true;
SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId);
// Check Strobe
cmsError = MEM_RWBoolean(R, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue);
if (cmsError.IsError())
return cmsError;
// If PLC it's performing another request then return
if (readValue)
return NO_ERROR;
// Check ACK
cmsError = MEM_RWBoolean(R, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue);
if (cmsError.IsError())
return cmsError;
// If PLC it's performing another request then return
if (readValue)
return NO_ERROR;
// Write strobe into memory
cmsError = MEM_RWBoolean(W, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref writeValue);
if (cmsError.IsError())
return cmsError;
// Reset wait ack = 1 and reset the strobe
cmsError = ResetStrobe(alarmBitId, strobeByte, ackByte, ackCell.MemType);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
private void SetupAckStrobeAddresses(int ackAddress, int strobeAddress, uint id, out int ackByte, out int strobeByte, out int bit)
{
ackByte = ackAddress + (((int)id - 1) / 8);
strobeByte = strobeAddress + (((int)id - 1) / 8);
bit = (((int)id - 1) % 8);
}
private CmsError ResetStrobe(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType)
{
int n = 600;
bool readValue = false;
bool writeValue = false;
bool ok = false;
CmsError cmsError;
do
{
// Check ACK
cmsError = MEM_RWBoolean(R, 0, memType, TABLE, ackByte, bitId, ref readValue);
if (cmsError.IsError())
return cmsError;
// If true reset strobe
if (readValue == true)
{
// Reset strobe
cmsError = MEM_RWBoolean(W, 0, memType, TABLE, strobeByte, bitId, ref writeValue);
if (cmsError.IsError())
return cmsError;
// Exit from cycle
n = 0;
ok = true;
}
else
{
// Decrement
n--;
// Wait befor next cycle
Thread.Sleep(20);
}
} while (n > 0);
if (!ok)
{
// Reset strobe
cmsError = MEM_RWBoolean(W, 0, memType, TABLE, strobeByte, bitId, ref writeValue);
if (cmsError.IsError())
return cmsError;
}
return cmsError;
}
private CmsError PLC_ManageActiveAck(int strobeByte, int strobeSubByte, int strobeBit, int ackByte, int ackSubByte, int ackBit, MEMORY_TYPE memType)
{
int n = 1200; // 30 seconds
bool readValue = false;
bool writeValue = true;
bool ok = false;
// Set ack to 1
CmsError cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
if (cmsError.IsError())
return cmsError;
do
{
// Check strobe
cmsError = MEM_RWBoolean(R, 0, memType, strobeByte, strobeSubByte, strobeBit, ref readValue);
if (cmsError.IsError())
return cmsError;
// If true reset acknowledge
if (!readValue)
{
writeValue = false;
// Reset acknowledge
cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
if (cmsError.IsError())
return cmsError;
// Exit from cycle
n = 0;
ok = true;
}
else
{
// Decrement
n--;
// Wait befor next cycle
Thread.Sleep(25);
}
} while (n > 0);
// If loop timeout goes in timeout
if (!ok)
{
// Reset acknowledge
writeValue = false;
cmsError = MEM_RWBoolean(W, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
if (cmsError.IsError())
return cmsError;
}
return cmsError;
}
public override CmsError PLC_WExpiredCandy(bool value)
{
bool newVal = false;
//Scrivo il dato
CmsError cmsError = MEM_RWBoolean(W, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value);
if (cmsError.IsError())
return cmsError;
else
{
//Leggo il dato
cmsError = PLC_RExpiredCandy(ref newVal);
if (cmsError.IsError())
return cmsError;
//Se i 2 dati coincidono ritorno OK
if (value == newVal)
return NO_ERROR;
else
return PLC_NOT_RUNNING_ERROR;
}
}
public override CmsError PLC_RExpiredCandy(ref bool value)
{
CmsError cmsError = MEM_RWBoolean(R, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PLC_WCandy(long value)
{
// Long is formed by a integer + word
// Write Word
ushort word = (ushort)((value & 0xFFFF));
CmsError cmsError = MEM_RWWord(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word);
if (cmsError.IsError())
return cmsError;
int integer = (int)((value & 0xFFFFFFFF0000) >> 16);
// Write Integer (+1 is used because osai uses word)
cmsError = MEM_RWInteger(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref integer);
if (cmsError.IsError())
return cmsError;
// Rieggo il dato
long newVal = 0;
cmsError = PLC_RCandy(ref newVal);
if (cmsError.IsError())
return cmsError;
// Se i 2 dati coincidono ritorno OK
if (value == newVal)
return NO_ERROR;
else
return PLC_NOT_RUNNING_ERROR;
}
public override CmsError PLC_RCandy(ref long value)
{
// Long is formed by a integer + word
// Read word
ushort word = 0;
CmsError cmsError = MEM_RWWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word);
if (cmsError.IsError())
return cmsError;
// Read first int
uint firtInt = 0;
cmsError = MEM_RWDWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref firtInt);
if (cmsError.IsError())
return cmsError;
// Build Long value
value = ((long)firtInt << 16) + word;
return NO_ERROR;
}
public override CmsError PLC_RActiveClient(ref int clientId)
{
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
byte readValues = 0;
cmsError = MEM_RWByte(R, 0, ACTIVE_CLIENT.MemType, ACTIVE_CLIENT.Address, ACTIVE_CLIENT.SubAddress, 0, ref readValues);
if (cmsError.IsError())
return cmsError;
// Convert integer array into bit array
bool[] statusBits = ByteToBits(readValues);
// check which bit is set
for (int i = 0; i < 8; i++)
{
if (statusBits[i])
clientId = i + 1;
}
return NO_ERROR;
}
public override CmsError PLC_RToolMovement(ref MovementBetweenMagazinesModel toolMovement)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError PLC_WTerminateMovementProcedure(MOVEMENT_RESPONSE resp)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
#endregion PLC High-level data
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region PROCESS (PATH) High-level data
// Get the process Mode
public override CmsError PROC_RMode(ushort ProcNumber, ref PROC_MODE Mode)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
// FIXME
// 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 cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
// FIXME
// fare guardando amppatura 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<string> 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<AlarmModel> alarms)
{
// 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;
// Read part program name
CmsError cmsError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName);
if (cmsError.IsError())
return cmsError;
int readValue = 0;
// Read processes status from memory
cmsError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address, PROCESS_STATUS.SubAddress + ((procNumber - 1) * 2), ref readValue);
if (cmsError.IsError())
return cmsError;
byte[] bytes = BitConverter.GetBytes(readValue);
// Convert Byte into true/false array
BitArray bits = new BitArray(new byte[] { bytes[0] }); // 1st byte -> 0 : Proccess type (AUX-WORK), 1: Process in alarm status, 2: Run, 3: Hold, 4: Read, 5: PartProgramVisible
// Get part program info visibility
processData.Visible = bits[0];
// Populate response structure
processData.Type = bits[1] ? "WORK" : "AUX";
processData.IsSelected = bits[2];
processData.IsInAlarm = bits[3];
processData.CanLoadProgram = bits[4];
// Choose process status
if (bytes[1] == 1)
processData.Status = "HOLD";
else
{
if (bytes[1] == 2)
processData.Status = "RUN";
else
processData.Status = "READY";
}
// Get Reps from 3nd-4th byte
processData.Reps = BitConverter.ToUInt16(bytes, 2);
return NO_ERROR;
}
public override CmsError PROC_RSelectedProcess(ref ushort procNumber)
{
if (SelectedProcess == 0)
return SELECTED_PROCESS_ERROR;
procNumber = SelectedProcess;
//CmsError cmsError;
//bool readValue = false;
//for (int i = 0; i < PROCESS_NUMBER; i++)
//{
// // Calculate bit address = ProcessBase + processId * 2
// int memoryAddress = SELECTED_PROCESS.SubAddress + i * (2);
// // Read memory from plc
// cmsError = MEM_RWBoolean(R, 0, SELECTED_PROCESS.MemType, SELECTED_PROCESS.Address, memoryAddress, 2, ref readValue);
// if (cmsError.IsError())
// return cmsError;
// if (readValue)
// {
// procNumber = (ushort)(i + 1);
// return NO_ERROR;
// }
//}
return NO_ERROR;
}
public override CmsError PROC_WSelectProcess(ushort procNumber)
{
CmsError cmsError;
byte processNum = (byte)procNumber;
// Check parameter
if (processNum > MAX_PROCESS_NUMBER)
return INCORRECT_PARAMETERS_ERROR;
// Write process number
cmsError = MEM_RWByte(W, 0, SELECT_PROCESS.MemType, SELECT_PROCESS.Address, SELECT_PROCESS.SubAddress, ref processNum);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
}
public override CmsError PROC_RSelectedProcessData(int processId, ref SelectedProcessData processData)
{
if (processId <= 0)
return PROC_NOT_FOUND_ERROR;
// FIXME
// 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<EdgeConfigModel> 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;
#if false
try
{
Item item = new Item();
if (processId == 0)
item.Path = "/Channel/ProgramInfo/actBlock[u1,1]"; // Default
else
item.Path = "/Channel/ProgramInfo/actBlock[u" + processId + ",1]";
DataSvc dataSvc = new DataSvc();
dataSvc.Read(item);
line = item.Value.ToString();
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
#endregion PROCESS (PATH) High-level data
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region PROCESS-AXES (PATH) High-level data
public override CmsError AXES_RInterpPosition(ushort channel, ref Dictionary<string, double> axes)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
try
{
axes = new Dictionary<string, double>();
// Cycle between axes
// The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
// axes = InterpAxesPosition.ToDictionary(x => x.Key, x => x.Value); This code throws exceptions
lock (InterpAxesPosition)
{
foreach (var axis in InterpAxesPosition.ToList())
{
axes.Add(axis.Key, axis.Value);
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
public override CmsError AXES_RMachinePosition(ushort channel, ref Dictionary<string, double> axes)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
try
{
axes = new Dictionary<string, double>();
lock (MachineAxesPosition)
{
// Cycle between axes
// The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
foreach (var axis in MachineAxesPosition.ToList())
{
axes.Add(axis.Key, axis.Value);
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
public override CmsError AXES_RProgrPosition(ushort channel, ref Dictionary<string, double> axes)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
try
{
axes = new Dictionary<string, double>();
lock (ProgrammedAxisPosition)
{
// Cycle between axes
// The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
foreach (var axis in ProgrammedAxisPosition.ToList())
{
axes.Add(axis.Key, axis.Value);
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
public override CmsError AXES_RFollowingError(ushort channel, ref Dictionary<string, double> axes)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
try
{
axes = new Dictionary<string, double>();
lock (InterpAxesPosition)
{
// Cycle between axes
// The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
foreach (var axis in InterpAxesPosition.ToList())
{
axes.Add(axis.Key, axis.Value);
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
public override CmsError AXES_RDistanceToGo(ushort channel, ref Dictionary<string, double> axes)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
try
{
axes = new Dictionary<string, double>();
lock (ToGoAxesPosition)
{
// Cycle between axes
// The dictionary is written asynchronously so i have to create a copy of the dictionary with .ToList() to avoid exceptions
foreach (var axis in ToGoAxesPosition.ToList())
{
axes.Add(axis.Key, axis.Value);
}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
private Dictionary<string, double> AXES_RAxesPos(ushort channel, string positionType)
{
Dictionary<string, double> axes = new Dictionary<string, double>();
#if false
List<AxisModel> axesConf = new List<AxisModel>();
CmsError cmsError = AXES_RAxesNames(channel, ref axesConf);
List<Item> items = new List<Item>();
foreach (var conf in axesConf)
{
// Setup the items to be readed
items.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", positionType, channel, conf.Id) });
}
DataSvc dataSvc = new DataSvc();
// Read all the items
dataSvc.Read(items.ToArray());
int i = 0;
foreach (var conf in axesConf)
{
axes.Add(conf.Id.ToString(), Convert.ToDouble(items[i].Value));
i++;
}
#endif
return axes;
}
public override CmsError AXES_RAxesNames(ushort channel, ref List<AxisModel> axesData)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
if (!File.Exists(AXES_FILE_PATH))
return CmsError.InternalError("File" + AXES_FILE_PATH + " not found", new Exception("File" + AXES_FILE_PATH + " not found"));
// Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
List<AxisModel> configuredAxes = new List<AxisModel>();
Item[] ncAxes = new Item[MAX_AXES_FOR_PROCESS * 3];
try
{
// Check if the static object is already populated
if (AxesData.Count == 0)
{
XDocument xmlAxesFile = XDocument.Load(AXES_FILE_PATH);
// Read data from file
configuredAxes = xmlAxesFile
.Root
.Elements()
.Select(x => new AxisModel()
{
Id = Convert.ToInt32(x.Attribute("id").Value),
Name = x.Value,
IsSelectable = false
})
.Where(x => x.Id != 0) // Parse only active axes
.ToList();
}
// Object used for reading data from NC
DataSvc svcData = new DataSvc();
bool[] axesAreVisible = new bool[MAX_AXES_FOR_PROCESS];
// Read from Nc
for (int i = 1; i <= MAX_AXES_FOR_PROCESS; i++)
{
// Set the path to read on which process is the axis
ncAxes[i - 1] = new Item("/Nck/MachineAxis/chanNoAxisIsActive[" + i + "]");
// Set the path in order to find which axes are visible
ncAxes[i - 1 + MAX_AXES_FOR_PROCESS] = new Item("/NC/_N_CH_TEA_ACX/$MC_DISPLAY_AXIS[u" + channel + "," + i + "]");
// Set the path of the axes type
ncAxes[i - 1 + (MAX_AXES_FOR_PROCESS * 2)] = new Item("/Nck/Configuration/axisType[" + i + "]");
}
svcData.Read(ncAxes);
for (int i = 0; i < MAX_AXES_FOR_PROCESS; i++)
{
// Set visible field
axesAreVisible[i] = (Convert.ToInt32(ncAxes[i + MAX_AXES_FOR_PROCESS].Value) & 1) == 1;
int processAxes = Convert.ToInt32(ncAxes[i].Value);
// If axis is visible, add it to the output
if (processAxes == channel && axesAreVisible[i])
{
// Check if axes is configurated axes
var axis = configuredAxes.Where(x => x.Id == (i + 1)).FirstOrDefault();
if (axis != null)
{
axis.Type = (AXIS_TYPE)Convert.ToInt32(ncAxes[i + (MAX_AXES_FOR_PROCESS * 2)].Value);
AxesData.Add(axis);
}
}
}
// Get from PLC which axis can be selected
List<byte> ids = new List<byte>();
cmsError = MEM_RWByteList(R, 0, AXES_BUTTON_VISIBLE.MemType, AXES_BUTTON_VISIBLE.Address, AXES_BUTTON_VISIBLE.SubAddress, 0, AXES_BUTTON_VISIBLE.Size, ref ids);
if (cmsError.IsError())
return cmsError;
// Parse the data readed from PLC
foreach (byte id in ids)
{
if (id != 0)
{
// If axis exists, set it as selectable
var tmpAxis = AxesData.Where(x => x.Id == id).FirstOrDefault();
if (tmpAxis != null)
tmpAxis.IsSelectable = true;
}
}
axesData = AxesData;
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
}
public override CmsError AXES_RSelectedAxis(ref byte axisId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
// Read byte from memory
CmsError cmsError = MEM_RWByte(R, 0, SELECTED_AXIS.MemType, SELECTED_AXIS.Address, SELECTED_AXIS.SubAddress, 1, ref axisId);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
#endif
}
public override CmsError AXES_WSelectAxis(byte axisId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
// Write byte from memory
CmsError cmsError = MEM_RWByte(W, 0, SELECT_AXIS.MemType, SELECT_AXIS.Address, SELECT_AXIS.SubAddress, 1, ref axisId);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
#endif
}
public override CmsError AXES_ROrigin(int numberOfAxes)
{
return FUNCTION_NOT_ALLOWED_ERROR;
#if false
DataSvc dataSvc = new DataSvc();
List<Item> ncAxes = new List<Item>();
List<AxisModel> axes = new List<AxisModel>();
CmsError cmsError = AXES_RAxesNames(1, ref axes);
for (int i = 1; i <= 4; i++)
{
foreach (var axis in axes)
{
var num = axis.Id + (axes.Last().Id * i);
ncAxes.Add(new Item()
{
Path = "/Channel/UserFrame/linShift[u1, " + num + "]"
});
}
}
dataSvc.Read(ncAxes.ToArray());
return NO_ERROR;
#endif
}
#endregion PROCESS-AXES (PATH) High-level data
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region NC Low-level function: single valiable in memory
//Read-Write a Boolean-Value inside the NC.
public override CmsError MEM_RWBoolean(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemBit, ref bool Value)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
//Check if the Bit Number is Correct
cmsError = CheckBitRange(MemBit);
if (cmsError.IsError())
return cmsError;
byte bValue = 0;
ushort pow = (ushort)Math.Pow(2, MemBit);
//Read the Byte where is the bit
cmsError = MEM_RWByte(R, Process, MemType, MemTable, MemIndex, ref bValue);
if (cmsError.IsError())
return cmsError;
//If i have to Write -> Write the Bit
if (bWrite)
{
if (Value)
bValue = (byte)(bValue | (1 << MemBit));
else
bValue = (byte)(bValue & ~(1 << MemBit));
cmsError = MEM_RWByte(W, Process, MemType, MemTable, MemIndex, ref bValue);
if (cmsError.IsError())
return cmsError;
}
//If i have to read -> Read the Bit
else
{
Value = (bValue & pow) == pow;
}
return NO_ERROR;
}
//Read-Write a Byte-Value-List inside the NC. In writing-mode the field "Number" is not required
public override CmsError MEM_RWByte(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByte, ref byte Value)
{
List<byte> ListValue = new List<byte>() { Value };
//uses the List method with one-element list
CmsError cmsError = MEM_RWByteList(bWrite, Process, MemType, MemTable, MemIndex, MemByte, 1, ref ListValue);
if (cmsError.IsError())
return cmsError;
Value = ListValue.First();
return NO_ERROR;
}
//Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref ushort Value)
{
List<ushort> ListValue = new List<ushort>() { Value };
//uses the List method with one-element list
CmsError cmsError = MEM_RWWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
if (cmsError.IsError())
return cmsError;
Value = ListValue.First();
return NO_ERROR;
}
public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref short Value)
{
List<short> ListValue = new List<short>() { Value };
//uses the List method with one-element list
CmsError cmsError = MEM_RWShortList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
if (cmsError.IsError())
return cmsError;
Value = ListValue.First();
return NO_ERROR;
}
//Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref uint Value)
{
List<uint> ListValue = new List<uint>() { Value };
//uses the List method with one-element list
CmsError cmsError = MEM_RWDWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
if (cmsError.IsError())
return cmsError;
Value = ListValue.First();
return NO_ERROR;
}
public override CmsError MEM_RWDouble(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref double Value)
{
List<double> ListValue = new List<double>() { Value };
//uses the List method with one-element list
CmsError cmsError = MEM_RWDoubleList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
if (cmsError.IsError())
return cmsError;
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<int> ListValue = new List<int>() { Value };
//uses the List method with one-element list
CmsError cmsError = MEM_RWIntegerList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
if (cmsError.IsError())
return cmsError;
Value = ListValue.First();
return NO_ERROR;
}
//--------------------------------------------------------------------------------------------------------------------------
// Other-NC Version of Memory-Access Methods
public override CmsError MEM_RWBoolean(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemBit, ref bool Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWByte(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemByte, ref byte Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref uint Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWInteger(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref int Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref short Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, ref ushort Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWDouble(bool bWrite, int process, MEMORY_TYPE memType, int memIndex, ref double value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<uint> Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<int> Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<short> Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int Number, ref List<ushort> Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemIndex, int MemByteStart, int Number, ref List<byte> Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
#endregion NC Low-level function: single valiable in memory
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region Low level methods
public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByteStart, int Number, ref List<byte> Values)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
if (MemType != MEMORY_TYPE.Siemens_DB)
{
return INCORRECT_PARAMETERS_ERROR;
}
cmsError = null;
if (bWrite)
{
//Prevent some exceptions
if (Values.Count == 0)
return NO_ERROR;
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, Values.ToArray());
}
else
{
// Prevent some exceptions
if (Number == 0)
return NO_ERROR;
Values.Clear();
var memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
Values = memByteRead.ToList();
}
return NO_ERROR;
}
public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<ushort> Values)
{
////Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
if (MemType != MEMORY_TYPE.Siemens_DB)
{
return INCORRECT_PARAMETERS_ERROR;
}
cmsError = null;
if (bWrite)
{
//Prevent some exceptions
if (Values.Count == 0)
return NO_ERROR;
byte[] singleItem = new byte[2];
List<Byte> memByteList = new List<byte>();
foreach (var Item in Values)
{
singleItem = S7.Net.Types.Word.ToByteArray(Item);
memByteList.AddRange(singleItem);
}
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
}
else
{
// Prevent some exceptions
if (Number == 0)
return NO_ERROR;
Values.Clear();
byte[] 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);
}
}
return NO_ERROR;
}
public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<short> Values)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
if (MemType != MEMORY_TYPE.Siemens_DB)
{
return INCORRECT_PARAMETERS_ERROR;
}
cmsError = null;
if (bWrite)
{
//Prevent some exceptions
if (Values.Count == 0)
return NO_ERROR;
byte[] singleItem = new byte[2];
List<Byte> memByteList = new List<byte>();
foreach (var Item in Values)
{
singleItem = S7.Net.Types.Int.ToByteArray(Item);
memByteList.AddRange(singleItem);
}
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
}
else
{
// Prevent some exceptions
if (Number == 0)
return NO_ERROR;
Values.Clear();
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);
}
}
return NO_ERROR;
}
public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<uint> Values)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
if (MemType != MEMORY_TYPE.Siemens_DB)
{
return INCORRECT_PARAMETERS_ERROR;
}
cmsError = null;
if (bWrite)
{
//Prevent some exceptions
if (Values.Count == 0)
return NO_ERROR;
byte[] singleItem = new byte[4];
List<Byte> memByteList = new List<byte>();
foreach (var Item in Values)
{
singleItem = S7.Net.Types.DWord.ToByteArray(Item);
memByteList.AddRange(singleItem);
}
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
}
else
{
// Prevent some exceptions
if (Number == 0)
return NO_ERROR;
Values.Clear();
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);
}
}
return NO_ERROR;
}
public override CmsError MEM_RWIntegerList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<int> Values)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
if (MemType != MEMORY_TYPE.Siemens_DB)
{
return INCORRECT_PARAMETERS_ERROR;
}
cmsError = null;
if (bWrite)
{
//Prevent some exceptions
if (Values.Count == 0)
return NO_ERROR;
byte[] singleItem = new byte[4];
List<Byte> memByteList = new List<byte>();
foreach (var Item in Values)
{
singleItem = S7.Net.Types.DInt.ToByteArray(Item);
memByteList.AddRange(singleItem);
}
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
}
else
{
// Prevent some exceptions
if (Number == 0)
return NO_ERROR;
Values.Clear();
byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
// converto a word!
int shortVal = 0;
for (int i = 0; i < memByteRead.Length / 4; i++)
{
shortVal = S7.Net.Types.DInt.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray());
Values.Add(shortVal);
}
}
return NO_ERROR;
}
public override CmsError MEM_RWDoubleList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<double> Values)
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
if (MemType != MEMORY_TYPE.Siemens_DB)
{
return INCORRECT_PARAMETERS_ERROR;
}
cmsError = null;
if (bWrite)
{
//Prevent some exceptions
if (Values.Count == 0)
return NO_ERROR;
byte[] singleItem = new byte[4];
List<Byte> memByteList = new List<byte>();
foreach (var Item in Values)
{
singleItem = S7.Net.Types.Double.ToByteArray(Item);
memByteList.AddRange(singleItem);
}
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
}
else
{
// Prevent some exceptions
if (Number == 0)
return NO_ERROR;
Values.Clear();
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);
}
}
return NO_ERROR;
}
#endregion Low level methods
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region NC Low-level function: Parameters
public override CmsError NC_RParam(short Index, short Bit, ref bool Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError NC_RParam(short Index, ref byte Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError NC_RParam(short Index, ref short Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError NC_RParam(short Index, ref int Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError NC_RParam(short Index, ref double Value)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
#endregion NC Low-level function: Parameters
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region File Management
/// <summary>
/// Get list of recipe (from local PC area)
/// </summary>
/// <param name="path"></param>
/// <param name="file"></param>
/// <returns></returns>
public CmsError FILES_RecipeList(string path, ref List<PreviewFileModel> file)
{
return NO_ERROR;
}
/// <summary>
/// Load selected recipe, convert and save to PLC memory area
/// </summary>
/// <param name="path"></param>
/// <param name="name"></param>
/// <returns></returns>
public CmsError FILES_LoadRecipe(string path, string name)
{
return NO_ERROR;
}
/// <summary>
/// Save current recipe from PLC memory area to file
/// </summary>
/// <param name="path"></param>
/// <param name="name"></param>
/// <returns></returns>
public CmsError FILES_SaveRecipe(string path, string name)
{
return NO_ERROR;
}
public override CmsError FILES_RGetFileList(string path, ref List<PreviewFileModel> files)
{
#if false
string[] rootFolders = { "WKS.DIR", "MPF.DIR", "SPF.DIR" };
try
{
string tmpPath = FormatPath(path);
FileSvc fileSvc = new FileSvc();
// Preapare folder node
Node folderNode = new Node(BASE_FILE_PATH + tmpPath);
// Read files in the folder
List<Node> nodeArray = fileSvc.List(folderNode).ToList();
// Go through the array of file nodes
foreach (Node element in nodeArray)
{
PreviewFileModel file = new PreviewFileModel();
if (path == "\\\\")
{
if (rootFolders.Contains(element.Name))
{
file = new PreviewFileModel()
{
Path = path + "\\" + element.Name,
IsDirectory = element.IsDirNode,
Name = GetStringUntilOrEmpty(element.Name, "."),
AbsolutePath = element.LogicalPath
};
files.Add(file);
}
}
else
{
file = new PreviewFileModel()
{
Path = path + "\\" + element.Name,
IsDirectory = element.IsDirNode,
Name = element.IsDirNode ? GetStringUntilOrEmpty(element.Name, ".") : element.Name,
AbsolutePath = element.LogicalPath
};
files.Add(file);
}
// ACCESS LEVEL CHECK (REMOVED TEMPORARILY)
//if (element.AccessRights.List == AccessLevel.KEY_0)
//{
// var file = new PreviewFileModel()
// {
// Path = path + "\\" + element.Name,
// IsDirectory = element.IsDirNode,
// Name = element.Name,
// AbsolutePath = element.LogicalPath
// };
// files.Add(file);
//}
}
}
catch (Exception ex)
{
return ManageException(ex);
}
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_RGetFileInfo(string path, ref InfoFile fileInfo)
{
#if false
try
{
FileSvc fileSvc = new FileSvc();
// Preapare folder node
Node fileNode = new Node(path);
if (fileNode != null)
{
string filePath = "C://CMS//Active//TMP//" + fileNode.Name;
FileStream str = new FileStream(filePath, FileMode.Create);
CmsError cmsError = FILES_RProgramToFile(path, str);
if (cmsError.IsError())
return cmsError;
fileInfo = new InfoFile()
{
CreationDate = fileNode.Attributes.LastAccess,
LastModDate = fileNode.Attributes.LastAccess,
Name = fileNode.Name,
Content = File.ReadAllLines(filePath).ToList(),
// PreviewBase64 = FindImageBase64String(IMAGES_PATH, fileNode.Name),
AbsolutePath = fileNode.LogicalPath
};
str.Close();
File.Delete(filePath);
}
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_WSetActiveProgram(int processId, string filePath, ref ActiveProgramDataModel data)
{
#if false
try
{
// string ncPath = FormatPath(filePath);
FileSvc fileSvc = new FileSvc();
// Preapare folder node
Node selectedNode = new Node(filePath);
if (!selectedNode.Exists)
return FILE_NOT_FOUND_ERROR;
// Check if file is stored on NC
if (filePath.StartsWith(BASE_FILE_PATH))
fileSvc.Select(selectedNode, processId);
else
fileSvc.SelectExtern(selectedNode, processId);
return FILES_RActiveProgramData(processId, ref data);
}
catch (Exception ex)
{
return ManageException(ex);
}
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_WDeactivateProgram(int processId)
{
#if false
try
{
string[] piArgs = new string[4];
piArgs[0] = "/NC";
piArgs[1] = (200 + processId).ToString();
piArgs[2] = "/MPF0";
piArgs[3] = "_N_SELECT";
PiSvc pi = new PiSvc(piArgs);
pi.Start();
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_RActiveProgramData(int processId, ref ActiveProgramDataModel programData)
{
#if false
try
{
//Setup variables
DataSvc dataSvc = new DataSvc();
// Read position and tool data
List<Item> itemRead = new List<Item>()
{
new Item($"/Channel/ProgramInfo/workPandProgName[u{processId}]"),
new Item($"/Channel/ProgramInfo/actPartProgram[u{processId}]")
};
//Read Data
dataSvc.Read(itemRead.ToArray());
// Elaborate String
string trimString = ((string)itemRead[0].Value);
trimString = trimString.Replace("_N_", "");
int lastUnderscore = trimString.LastIndexOf("_");
if (lastUnderscore >= 0)
trimString = trimString.Remove(lastUnderscore, 1).Insert(lastUnderscore, ".");
// check if is the NULL Program
if (trimString == "/MPF0")
{
programData = new ActiveProgramDataModel()
{
Path = "",
IsoLines = new List<string>(),
TimeLeft = new DateTime()
};
return NO_ERROR;
}
// Separate string into list of lines
List<string> isoLines = itemRead[1]
.Value
.ToString()
.Split('\n') // Line separator
.Skip(1) // The actPartProgram read starting with the line before the current
.ToList();
programData = new ActiveProgramDataModel()
{
Path = trimString,
IsoLines = isoLines,
TimeLeft = new DateTime()
};
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_UploadPartProgram(string localPath, string name, ref string newFilePath)
{
#if false
File.Copy(localPath + name, PART_PRG_PATH + name, true);
newFilePath = PART_PRG_PATH + name;
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_CopyProgram(string partProgramPath, string newPartProgramPath, bool failIfExist)
{
#if false
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
try
{
//Setup variables
FileSvc FileData = new FileSvc();
Node sourceNode = new Node(partProgramPath);
Node destNode = new Node(newPartProgramPath);
//Execute Function
FileData.Copy(sourceNode, destNode, failIfExist);
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_DeleteProgram(string partProgramPath, string partProgramName)
{
#if false
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
try
{
// Setup variables
FileSvc FileData = new FileSvc();
Node sourceNode = new Node(partProgramPath);
//Execute Function
FileData.Delete(sourceNode);
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_RProgramToFile(string partProgramPath, FileStream localFile)
{
#if false
// Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
try
{
// Setup variables
string tmpFile = Path.GetTempFileName();
FileSvc FileData = new FileSvc();
Node sourceNode = new Node(partProgramPath);
Node destNode = new Node(tmpFile);
// Execute Function
FileData.Copy(sourceNode, destNode, true);
FileStream tmpFileStream = new FileStream(tmpFile, FileMode.Open);
// Write to local file
WriteLocalFile(ReadLocalFile(tmpFileStream), ref localFile);
tmpFileStream.Close();
// Delete temporary file
File.Delete(tmpFile);
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_WProgramFromFile(string partProgramPath, FileStream localFile)
{
#if false
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
try
{
// Setup variables
FileSvc FileData = new FileSvc();
Node sourceNode = new Node(localFile.Name);
Node destNode = new Node(partProgramPath);
//Execute Function
FileData.Copy(sourceNode, destNode, true);
}
catch (Exception ex)
{
return ManageException(ex);
}
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError FILES_RQueueData(ref List<QueueStatusModel> 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)
{
#if false
string customMainName = string.Format(CUSTOM_MAIN_PROGRAM, processId);
string newFilePath = "";
CmsError cmsError = FILES_UploadPartProgram(customPartProgramContent, customMainName, ref newFilePath);
if (cmsError.IsError())
return cmsError;
cmsError = FILES_WSetActiveProgram(processId, newFilePath, ref activeData);
if (cmsError.IsError())
return cmsError;
return NO_ERROR;
#endif
return FUNCTION_NOT_ALLOWED_ERROR;
}
private IEnumerable<string> 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<SiemensToolModel> toolTable)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RShanksData(ref List<ShankModel> shanksData)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RFamilyData(ref List<FamilyModel> families)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RMagazinePositions(ref List<PositionModel> positions)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WAddTool(ref SiemensToolModel tool)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WAddFamily(ref FamilyModel family)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WAddShank(ref ShankModel shank)
{
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)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WDeleteEdge(int toolId, int edgeId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WAddEdge(int toolId, ref EdgeModel edge)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WUpdateEdge(int toolId, ref EdgeModel newEdge)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WUpdateShank(ref ShankModel shank)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RMountedTools(int magazineId, ref List<MountedToolModel> magazinePos)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RAvailableTools(ref List<ShankModel> multiTools, ref List<SiemensToolModel> tools)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WLoadToolInMagazine(int magazine, NewToolInMagazineModel newMagazineTool, ref MountedToolModel newMountedTool)
{
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)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WStartTDILoading(ushort magazineId, ushort positionId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WStartTDIUnloading(ushort magazineId, ushort positionId, ushort toolId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WEmptyBallufTablet(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<NcMagazineConfigModel> 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<NcToolModel> list)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WUpdateFamilies(List<NcFamilyModel> list)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WUpdateShanks(List<NcShankModel> list)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WUpdateMagazinePositions(List<NcMagazinePositionModel> list)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WStartEditTooling(int magazineId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WStopEditTooling(int magazineId)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WRestoreBackup()
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RUpdatedToolsData(ref Dictionary<int, byte> updatedStatus, ref Dictionary<int, uint> updatedLives)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RStoredData(ref List<NcToolModel> tools, ref List<NcFamilyModel> families, ref List<NcShankModel> shanks)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RMagazineBlock(ref List<int> ids)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WFreeMagazines()
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RMagazineStatus(ref Dictionary<int, bool> magazineStatus)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_RAdatpivePathStep(ref Byte step)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
public override CmsError TOOLS_WAdatpivePathStep(Byte step)
{
return FUNCTION_NOT_ALLOWED_ERROR;
}
#endregion Nc Tool Manager
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region Subordinate Private Functions
#if false
// Manage the Alarms - Called automatically on changes
private void AlarmsChanged(Guid guid, Alarm[] alarms)
{
try
{
if (alarms != null)
SiemensAlarms = alarms.ToArray();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
#endif
private void NcLanguageChanged(string language)
{
#if false
SiemensAlmSvc.UnSubscribe(AlarmsChanged);
// SiemensAlmSvc.Dispose();
SiemensAlmSvc = new AlarmSvc(language);
SiemensAlmSvc.Subscribe(AlarmsChanged);
#endif
}
private int SetBitValue(int intVal, bool val, int bitIndex)
{
if (val)
return intVal | (1 << (bitIndex - 1));
else
return intVal & ~(1 << (bitIndex - 1));
}
//Manage the Mode
private PROC_MODE ConvertToSTEPMode(uint mode, uint JogMode, uint AdvMode)
{
if (mode == 0)
{
if (AdvMode == 0)
return (JogMode < 6) ? PROC_MODE.JOGINC : PROC_MODE.JOG;
else if (AdvMode == 1)
return PROC_MODE.RETPROF;
else if (AdvMode == 2)
return PROC_MODE.TEACH;
else if (AdvMode == 3)
return PROC_MODE.REF;
}
else if (mode == 1)
return PROC_MODE.MDI;
else if (mode == 2)
return PROC_MODE.AUTO;
return PROC_MODE.ERROR;
}
//Manage the Status
private PROC_STATUS ConvertToSTEPStatus(uint status)
{
switch (status)
{
case 0: return PROC_STATUS.IDLE;
case 1: return PROC_STATUS.RUN;
case 2: return PROC_STATUS.HOLD;
}
return PROC_STATUS.ERROR;
}
//Check Bit In Range
private CmsError CheckBitRange(int bitnum)
{
if (bitnum < 0 || bitnum > 7)
return BIT_NOT_IN_RANGE_ERROR;
return NO_ERROR;
}
// Check if Memory Area is corrected
private CmsError ConvertMemToPath(MEMORY_TYPE MemoryType, int Address, int SubAddress, int SubBit, int Qty, char MemAccess, out string item)
{
char[] allowedAccess = { 'X', 'B', 'W', 'D' };
//Check if is the right area and allowed type
if (!MemoryType.ToString().StartsWith(SIEMENS_MEMTYPE) || !allowedAccess.Contains(MemAccess) || Qty < 1)
{
item = "";
return INCORRECT_PARAMETERS_ERROR;
}
else
{
//If is Bit Access change access type
if (MemAccess == 'X')
item = "DB" + Address + ".DB" + MemAccess + SubAddress + "." + SubBit;
else
item = "DB" + Address + ".DB" + MemAccess + SubAddress + "[" + Qty + "]";
return NO_ERROR;
}
}
// Check if NC is connected
private CmsError CheckConnection()
{
if (!NC_IsConnected())
return NOT_CONNECTED_ERROR;
return NO_ERROR;
}
/// <summary>
/// Check if PLC is responding to Ping
/// </summary>
/// <returns></returns>
private CmsError CheckS7Ping()
{
// faccio ping...
if (testPing() != IPStatus.Success)
return PLC_IP_NOT_FOUND_ERROR;
return NO_ERROR;
}
/// <summary>
/// Ping test to configured Ip address
/// </summary>
/// <returns></returns>
private IPStatus testPing()
{
IPStatus answ = IPStatus.Unknown; ;
IPAddress address;
PingReply reply;
Ping pingSender = new Ping();
address = IPAddress.Loopback;
IPAddress.TryParse(this.Ip, out address);
reply = pingSender.Send(address, 100);
answ = reply.Status;
return answ;
}
//Manage the Exception Launch
private CmsError ManageException(Exception ex)
{
// Catch the 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);
}
}
// Create and return CmsError object
private CmsError GetError(string message)
{
return CmsError.NcError(message);
}
//Read Static Data
private CmsError ReadStaticNCData()
{
//Check if the NC is Connected
CmsError cmsError = CheckConnection();
if (cmsError.IsError())
return cmsError;
// Read oly one time every X seconds
if (DateTime.Now - Last_Static_Read > new TimeSpan(NC_MIN_SEC_READ_STATIC_DATA * TimeSpan.TicksPerSecond))
{
//Try to get information
try
{
// completare nuove variabili (matricola macchina, seriale PLC, firmware PLC)
ConfChannelNo = 1;
Last_Static_Read = DateTime.Now;
Cnc_name = $"{currPLC.CPU}";
// FIXME
Cms_MachNumber = ""; // matricola macchina, DB604.DBB6720..6723
Cnc_SftVersion = "SMC000"; // versione SW del firmware PLC/CNC | DB604.DBB6724..6745
Cnc_SeriesNum = "SMC111"; // seriale PLC/CNC | DB604.DBB6746..6763
PlcRirm_SeriesNum = "V.0.0.0"; // seriale PLC/CNC | DB604.DBB6764..6767
UnitOfMeasure = MILLIMETERS;
}
catch (Exception ex)
{
return ManageException(ex);
}
}
return NO_ERROR;
}
// Convert the internal Name var in Readable STEP Name
private string GetName(uint value)
{
string name = "Siemens ";
switch (value)
{
case 0: name += "840D pl"; break;
case 1000: name += "FM-NC"; break;
case 2000: name += "810D pl"; break;
case 3000: name += "802S"; break;
case 4000: name += "802D pl"; break;
case 5000: name += "840Di pl"; break;
case 6000: name += "SOLUTIONLINE"; break;
case 10700: name += "840D sl"; break;
case 14000: name += "802D sl T/M - N/G - C/U"; break;
case 15000: name += "840Di sl"; break;
}
return name;
}
//Convert to Step Language
private CultureInfo ConvertToSTEPLanguage(uint language)
{
switch (language)
{
case 1: return new CultureInfo("de");
case 2: return new CultureInfo("fr");
case 3: return new CultureInfo("en");
case 4: return new CultureInfo("es");
case 6: return new CultureInfo("it");
case 7: return new CultureInfo("nl");
case 8: return new CultureInfo("zh-CHS");
case 9: return new CultureInfo("sv");
case 18: return new CultureInfo("hu");
case 19: return new CultureInfo("fi");
case 26: return new CultureInfo("el");
case 28: return new CultureInfo("cs");
case 50: return new CultureInfo("pt-BR");
case 53: return new CultureInfo("pl");
case 55: return new CultureInfo("da");
case 57: return new CultureInfo("ru");
case 65: return new CultureInfo("hr-HR");
case 68: return new CultureInfo("sk");
case 69: return new CultureInfo("sl");
case 72: return new CultureInfo("ro");
case 75: return new CultureInfo("bg");
case 80: return new CultureInfo("zh-CHT");
case 85: return new CultureInfo("ko");
case 87: return new CultureInfo("ja");
case 89: return new CultureInfo("tr");
case 122: return new CultureInfo("id");
case 212: return new CultureInfo("th");
case 213: return new CultureInfo("vi");
case 230: return new CultureInfo("ms");
default: return new CultureInfo("en");
}
}
//Convert to Step Language
private string ConvertToNCLanguage(CultureInfo language)
{
return language.ThreeLetterISOLanguageName;
}
private int SwapIntEndianFormat(int value)
{
var b1 = (value >> 0) & 0xff;
var b2 = (value >> 8) & 0xff;
var b3 = (value >> 16) & 0xff;
var b4 = (value >> 24) & 0xff;
return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
}
private short SwapShortEndianFormat(short value)
{
var b1 = (value >> 0) & 0xff;
var b2 = (value >> 8) & 0xff;
return (short)(b1 << 8 | b2 << 0);
}
private ushort SwapShortEndianFormat(ushort value)
{
var b1 = (value >> 0) & 0xff;
var b2 = (value >> 8) & 0xff;
return (ushort)(b1 << 8 | b2 << 0);
}
private List<int> ChangeIntListEndianess(List<int> bigEndianvalues)
{
List<int> littleEndianValues = new List<int>();
foreach (int value in bigEndianvalues)
{
var a = SwapIntEndianFormat(value);
littleEndianValues.Add(a);
}
return littleEndianValues;
}
private List<ushort> ChangeUShortListEndianess(List<ushort> bigEndianvalues)
{
List<ushort> littleEndianValues = new List<ushort>();
foreach (ushort value in bigEndianvalues)
{
var a = SwapShortEndianFormat(value);
littleEndianValues.Add(a);
}
return littleEndianValues;
}
private bool PositionContainsTool(MountedToolModel mounted, int toolId)
{
if (mounted.ToolId == toolId)
return true;
//else
//{
// // Check if tool is a multitool child
// foreach (var multi in MultitoolsData)
// {
// // Check childs id
// int index = multi.ChildsTools.FindIndex(x => x.Id == toolId);
// if (index >= 0)
// return true;
// }
//}
return false;
}
//private void CheckData(object obj, List<FieldsConfiguration> config)
//{
// foreach(PropertyInfo prop in obj.GetType().GetProperties())
// {
// bool val = config.Where(x => x.Name == prop.Name).Select(x => x.);
// }
//}
private string ConvertStepToSiemensScreen(SCREEN_PAGE page)
{
switch (page)
{
case SCREEN_PAGE.Siemens_Machine: return "AreaMachine";
case SCREEN_PAGE.Siemens_Parameter: return "AreaParameter";
case SCREEN_PAGE.Siemens_Program: return "AreaProgramEdit";
case SCREEN_PAGE.Siemens_ProgramManager: return "AreaProgramManager";
case SCREEN_PAGE.Siemens_Setup: return "AreaStartup";
case SCREEN_PAGE.Siemens_Diagnostics: return "AreaDiagnosis";
default: return "";
}
}
#endregion Subordinate Private Functions
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#region THERMO high level data
public CmsError PLC_RRecipeParamList(bool onlyRT, ref List<RecipeParam> currParamList)
{
// refresh dati veloci / RT
refreshMemRecipeParameterRT();
// se richiesto NON SOLO RT faccio refresh anche dati "lenti"
if(!onlyRT)
{
refreshMemRecipeParameter();
}
// copio lista act in output...
currParamList = thermoParamList;
return NO_ERROR;
}
private void refreshMemRecipeParameterRT()
{
// leggo da PLC a array di byte di appoggio...
// converto a blocchi
// update oggetto thermoParamList...
}
private void refreshMemRecipeParameter()
{
// leggo da PLC a array di byte di appoggio...
// converto a blocchi
// update oggetto thermoParamList...
}
#endregion
}
internal static class MEMORY_ADDRESS
{
// Tabella DB principale
internal const int TABLE = 604;
// 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);
// 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_OCC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 64, 64);
internal static MEMORY_CELL RISC_CHP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 128, 1024);
internal static MEMORY_CELL RISC_CFI_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 2176, 1024);
internal static MEMORY_CELL RISC_ICH_MIN_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 3200, 4096);
internal static MEMORY_CELL RISC_OCS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 9472, 64);
internal static MEMORY_CELL RISC_ESP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 9728, 1024);
internal static MEMORY_CELL RISC_OVP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 10752, 1024);
internal static MEMORY_CELL RISC_ICH_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 500, 11776, 4096);
// produzione
internal static MEMORY_CELL PROCESS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 2);
// Machine number
internal static MEMORY_CELL NEW_MATR_MACC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 4);
internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 1);
internal static MEMORY_CELL ACTIVE_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 1);
internal static MEMORY_CELL ACTIVE_CLIENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4, 1);
internal static MEMORY_CELL FUNCTION_ACCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6, 8);
internal static MEMORY_CELL PRE_POST_POWER_ON = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2574, 2);
internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2576, 2);
internal static MEMORY_CELL PRE_POST_POWER_ON_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2578, 2);
internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2580, 2);
internal static MEMORY_CELL AXIS_RESET_PROCEDURE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2608, 1);
internal static MEMORY_CELL SELECTED_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2582, 24);
internal static MEMORY_CELL SELECT_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2606, 1);
internal static MEMORY_CELL COUNTERS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 40);
internal static MEMORY_CELL SELECTED_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2626, 1);
internal static MEMORY_CELL SELECT_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2627, 1);
internal static MEMORY_CELL NC_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2610, 4);
internal static MEMORY_CELL NC_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2614, 4);
internal static MEMORY_CELL NC_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2618, 4);
internal static MEMORY_CELL NC_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2622, 4);
internal static MEMORY_CELL USER_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2628, 16);
internal static MEMORY_CELL USER_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2644, 16);
internal static MEMORY_CELL USER_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2660, 16);
internal static MEMORY_CELL USER_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2676, 16);
internal static MEMORY_CELL ALARMS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 14, 128);
internal static MEMORY_CELL ALARMS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 142, 1024);
internal static MEMORY_CELL ALARM_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2190, 128);
internal static MEMORY_CELL ALARM_RESTORATION_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2318, 128);
internal static MEMORY_CELL ALARM_REFRESH_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2446, 128);
internal static MEMORY_CELL HEADS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2692, 240);
internal static MEMORY_CELL HEADS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2932, 4);
internal static MEMORY_CELL HEADS_STROBE_INCREMENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2936, 4);
internal static MEMORY_CELL HEADS_STROBE_DECREMENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2940, 4);
internal static MEMORY_CELL COUNTERS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2944, 64);
internal static MEMORY_CELL COUNTER_IS_RESETTABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3008, 2);
internal static MEMORY_CELL COUNTER_IS_RESETTABLE_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3010, 2);
internal static MEMORY_CELL COUNTER_IS_RESETTABLE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3012, 2);
internal static MEMORY_CELL M155_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3014, 1);
internal static MEMORY_CELL M155_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3015, 1);
internal static MEMORY_CELL M155_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3016, 1);
internal static MEMORY_CELL M156_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4333, 1);
internal static MEMORY_CELL M156_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4335, 1);
internal static MEMORY_CELL M156_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4337, 1);
internal static MEMORY_CELL M156_INPUT_ID_LIST = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4339, 8);
internal static MEMORY_CELL M154_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3042, 1);
internal static MEMORY_CELL M154_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3043, 1);
internal static MEMORY_CELL M154_SWITCH_ONOFF = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
internal static MEMORY_CELL AXES_BUTTON_VISIBLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3044, 16);
internal static MEMORY_CELL MAGAZINE_ACTION = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4000, 16);
//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);
}
}