6040 lines
233 KiB
C#
6040 lines
233 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.ServiceModel.Channels;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using static CMS_CORE_Library.Models.DataStructures;
|
|
using static CMS_CORE_Library.Nc;
|
|
using static CMS_CORE_Library.S7Net.MEMORY_ADDRESS;
|
|
using static CMS_CORE_Library.Utils.Nc_Utils;
|
|
|
|
namespace CMS_CORE_Library.S7Net
|
|
{
|
|
internal static class MEMORY_ADDRESS
|
|
{
|
|
// A) THERMO SPECIAL MEMORY
|
|
|
|
#region Internal Fields
|
|
|
|
// Main DB Table
|
|
internal const int TABLE = 604;
|
|
|
|
// B) GEN memory (NOT Thermo)
|
|
internal static MEMORY_CELL ACTIVE_CLIENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4, 1);
|
|
|
|
internal static MEMORY_CELL ALARM_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2190, 128);
|
|
|
|
internal static MEMORY_CELL ALARM_REFRESH_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2318, 128);
|
|
|
|
internal static MEMORY_CELL ALARM_RESTORATION_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2318, 128);
|
|
|
|
internal static MEMORY_CELL ALARMS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 142, 1024);
|
|
|
|
internal static MEMORY_CELL ALARMS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 14, 128);
|
|
|
|
// assi
|
|
internal static MEMORY_CELL AXES_BUTTON_VISIBLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3044, 16);
|
|
|
|
internal static MEMORY_CELL AXES_COMMAND = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 512, 512);
|
|
|
|
internal static MEMORY_CELL AXES_GEN_CONTROL = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 1026, 2);
|
|
|
|
internal static MEMORY_CELL AXES_GEN_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 1024, 2);
|
|
|
|
internal static MEMORY_CELL AXES_INFO = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 616, 0, 512);
|
|
|
|
internal static MEMORY_CELL AXES_RTDATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 615, 0, 768);
|
|
|
|
internal static MEMORY_CELL AXIS_RESET_PROCEDURE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2608, 1);
|
|
|
|
internal static MEMORY_CELL CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 130, 1);
|
|
|
|
internal static MEMORY_CELL COUNTER_IS_RESETTABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3008, 2);
|
|
|
|
internal static MEMORY_CELL COUNTER_IS_RESETTABLE_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3010, 2);
|
|
|
|
internal static MEMORY_CELL COUNTER_IS_RESETTABLE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3012, 2);
|
|
|
|
internal static MEMORY_CELL COUNTERS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 40);
|
|
|
|
internal static MEMORY_CELL COUNTERS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2944, 64);
|
|
|
|
internal static MEMORY_CELL EXP_CANDY_MEM = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 92, 1);
|
|
|
|
internal static MEMORY_CELL FIRMWARE_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6764, 4);
|
|
|
|
internal static MEMORY_CELL FUNCTION_ACCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6, 8);
|
|
|
|
internal static MEMORY_CELL HEAD_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 92, 4);
|
|
|
|
//old CMS-Control variables
|
|
internal static MEMORY_CELL HEADS_WORKED_TIMES = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 254, 60, 4);
|
|
|
|
internal static MEMORY_CELL IO_AI_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 132, 64);
|
|
|
|
internal static MEMORY_CELL IO_AI_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 388, 4);
|
|
|
|
internal static MEMORY_CELL IO_AO_FORCE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 524, 4);
|
|
|
|
internal static MEMORY_CELL IO_AO_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 196, 64);
|
|
|
|
internal static MEMORY_CELL IO_AO_VAL_FOR = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 528, 64);
|
|
|
|
internal static MEMORY_CELL IO_AO_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 392, 4);
|
|
|
|
internal static MEMORY_CELL IO_COMMW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 2, 2);
|
|
|
|
internal static MEMORY_CELL IO_DI_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 4, 64);
|
|
|
|
internal static MEMORY_CELL IO_DI_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 260, 64);
|
|
|
|
internal static MEMORY_CELL IO_DO_FORCE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 396, 64);
|
|
|
|
internal static MEMORY_CELL IO_DO_VAL_ACT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 68, 64);
|
|
|
|
internal static MEMORY_CELL IO_DO_VAL_FOR = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 460, 64);
|
|
|
|
internal static MEMORY_CELL IO_DO_VISIB = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 324, 64);
|
|
|
|
// gestione canali IO
|
|
internal static MEMORY_CELL IO_STATW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 628, 0, 2);
|
|
|
|
internal static MEMORY_CELL KEYBOARD_STAR_MEMORY = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6780, 2);
|
|
|
|
internal static MEMORY_CELL LOG_CYCLE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 617, 12, 1000);
|
|
|
|
internal static MEMORY_CELL M154_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3042, 1);
|
|
|
|
internal static MEMORY_CELL M154_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3043, 1);
|
|
|
|
internal static MEMORY_CELL M154_SWITCH_ONOFF = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
|
|
|
|
internal static MEMORY_CELL M156_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6770, 1);
|
|
|
|
internal static MEMORY_CELL M156_INPUT_ID_LIST = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6774, 2);
|
|
|
|
internal static MEMORY_CELL M156_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6768, 1);
|
|
|
|
//internal static MEMORY_CELL HEADS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2932, 4);
|
|
//internal static MEMORY_CELL HEADS_STROBE_INCREMENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2936, 4);
|
|
//internal static MEMORY_CELL HEADS_STROBE_DECREMENT = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2940, 4);
|
|
//internal static MEMORY_CELL M155_INPUT_NEEDED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3014, 1);
|
|
//internal static MEMORY_CELL M155_INPUT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3015, 1);
|
|
//internal static MEMORY_CELL M155_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 3016, 1);
|
|
internal static MEMORY_CELL M156_INPUT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6772, 1);
|
|
|
|
//internal static MEMORY_CELL HEADS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2692, 240);
|
|
internal static MEMORY_CELL M156_RESPONSE_MEMORY = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6776, 4);
|
|
|
|
// generic machine gauge data
|
|
internal static MEMORY_CELL MACHINE_GAUGE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 6, 16);
|
|
|
|
internal static MEMORY_CELL MACHINE_RESET_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 98, 4);
|
|
|
|
internal static MEMORY_CELL MACHINE_WORKED_TIME = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 255, 94, 4);
|
|
|
|
internal static MEMORY_CELL MAGAZINE_ACTION = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 4000, 16);
|
|
|
|
// aree Moduli
|
|
internal static MEMORY_CELL MODULE_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 602, 18, 2304);
|
|
|
|
internal static MEMORY_CELL MODULE_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 603, 12, 1536);
|
|
|
|
internal static MEMORY_CELL NC_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2618, 4);
|
|
|
|
internal static MEMORY_CELL NC_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2622, 4);
|
|
|
|
internal static MEMORY_CELL NC_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2614, 4);
|
|
|
|
internal static MEMORY_CELL NC_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2610, 4);
|
|
|
|
// watchdog
|
|
internal static MEMORY_CELL NC_WATCHDOG = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 1);
|
|
|
|
internal static MEMORY_CELL NEW_MATR_MACC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 4);
|
|
|
|
// aree Parametri
|
|
internal static MEMORY_CELL PARAMETER_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 600, 20, 8000);
|
|
|
|
// recipe edit confirmation/cancel strobe/ack
|
|
internal static MEMORY_CELL PARAMETER_EDIT_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
|
|
|
|
internal static MEMORY_CELL PARAMETER_EDIT_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2);
|
|
internal static MEMORY_CELL PARAMETER_RT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 601, 8, 3200);
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6542, 4);
|
|
|
|
// C) STD MEM (need check!) FIXME TODO
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2578, 2);
|
|
|
|
internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2580, 2);
|
|
|
|
internal static MEMORY_CELL PROCESS_PROD_CYCLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 22);
|
|
|
|
// produzione
|
|
internal static MEMORY_CELL PROCESS_PROD_INFO = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 606, 0, 52);
|
|
|
|
internal static MEMORY_CELL PROCESS_STATUS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 605, 0, 2);
|
|
|
|
// Prod strobe/ack
|
|
internal static MEMORY_CELL PROD_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
|
|
|
|
internal static MEMORY_CELL PROD_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2);
|
|
|
|
internal static MEMORY_CELL REQ_CONF_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2);
|
|
|
|
// strobe received from PLC
|
|
internal static MEMORY_CELL REQ_CONF_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
|
|
|
|
// Mode request strobe/ack
|
|
internal static MEMORY_CELL REQ_MODE_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 2);
|
|
|
|
internal static MEMORY_CELL REQ_MODE_STROBE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2, 2);
|
|
internal static MEMORY_CELL RISC_CFI_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 2176, 1024);
|
|
|
|
// riscaldi
|
|
internal static MEMORY_CELL RISC_CHP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 614, 0, 1024);
|
|
|
|
internal static MEMORY_CELL RISC_ESP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 9728, 1024);
|
|
|
|
internal static MEMORY_CELL RISC_ICH_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 11776, 4096);
|
|
|
|
internal static MEMORY_CELL RISC_ICH_MIN_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 3200, 4096);
|
|
|
|
internal static MEMORY_CELL RISC_OCC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 64, 64);
|
|
|
|
internal static MEMORY_CELL RISC_OCS_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 9472, 64);
|
|
|
|
internal static MEMORY_CELL RISC_OVP_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 10752, 1024);
|
|
|
|
internal static MEMORY_CELL RISC_PLC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 627, 0, 1024);
|
|
|
|
internal static MEMORY_CELL RISC_VU_MIN = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 513, 0, 2);
|
|
|
|
internal static MEMORY_CELL SELECT_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2627, 1);
|
|
|
|
internal static MEMORY_CELL SELECT_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2606, 1);
|
|
|
|
internal static MEMORY_CELL SELECTED_AXIS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2626, 1);
|
|
|
|
internal static MEMORY_CELL SELECTED_PROCESS = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2582, 24);
|
|
|
|
internal static MEMORY_CELL SER_NUM_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6746, 22);
|
|
|
|
// Machine data
|
|
internal static MEMORY_CELL STATIC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6720, 48);
|
|
|
|
// status/command data
|
|
internal static MEMORY_CELL STATUS_CMD_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 0, 4);
|
|
|
|
internal static MEMORY_CELL TCAM_CH_ENAB_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 4, 128);
|
|
|
|
internal static MEMORY_CELL TCAM_COMMW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 2, 2);
|
|
|
|
//internal static MEMORY_CELL RISC_PLC_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 514, 128, 1024); //valore PRE thermoCam
|
|
// ThermoCamera
|
|
internal static MEMORY_CELL TCAM_STATW_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 626, 0, 2);
|
|
|
|
internal static MEMORY_CELL TCAM_TEMP_ACT_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 625, 0, 2048);
|
|
internal static MEMORY_CELL TCAM_TEMP_REQ_DATA = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 624, 0, 2048);
|
|
|
|
internal static MEMORY_CELL USER_SOFT_KEYS_ACK = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6584, 16);
|
|
internal static MEMORY_CELL USER_SOFT_KEYS_CLICKED = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6600, 16);
|
|
internal static MEMORY_CELL USER_SOFTKEYS_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6568, 16);
|
|
internal static MEMORY_CELL USER_SOFTKEYS_VALUE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 6552, 16);
|
|
internal static MEMORY_CELL VERS_SW_PLC = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, 604, 6724, 22);
|
|
|
|
#endregion Internal Fields
|
|
|
|
//internal static MEMORY_CELL PRE_POST_POWER_ON_CLICKABLE = new MEMORY_CELL(MEMORY_TYPE.Siemens_DB, TABLE, 2576, 2);
|
|
}
|
|
|
|
public class Nc_S7Net : NcThermo
|
|
{
|
|
// Global Constants
|
|
|
|
#region Private Fields
|
|
|
|
private const string NcNotFound = "Missing response";
|
|
private const string NcNotFound2 = "networking error";
|
|
private const string NcNotFound3 = "Nc not Connected";
|
|
|
|
private const string THERMO_DICT_PATH = @"Dict\";
|
|
|
|
/// <summary>
|
|
/// Lock per connessione PLC
|
|
/// </summary>
|
|
private readonly static object connectLock = new object();
|
|
|
|
private static string Cms_MachNumber;
|
|
|
|
private static string Cnc_name;
|
|
|
|
private static string Cnc_SeriesNum;
|
|
|
|
private static string Cnc_SftVersion;
|
|
|
|
private static uint ConfChannelNo;
|
|
|
|
// Global Variables
|
|
private static DateTime Last_Static_Read;
|
|
|
|
private static string PlcFirmware_SerialNum;
|
|
|
|
// Alarms data
|
|
private static Dictionary<int, string> PlcMessages = new Dictionary<int, string>();
|
|
|
|
private static ushort SelectedProcess = 1;
|
|
private static ThermoModels.ThermoCam ThermoCamData = new ThermoModels.ThermoCam();
|
|
private static ThermoModels.ChanIOFor ThermoIOFor = new ThermoModels.ChanIOFor();
|
|
private static ThermoModels.ChanIOVal ThermoIOVal = new ThermoModels.ChanIOVal();
|
|
private static ThermoModels.ChanIOValFor ThermoIOValFor = new ThermoModels.ChanIOValFor();
|
|
private static ThermoModels.ChanIOVis ThermoIOVis = new ThermoModels.ChanIOVis();
|
|
private static Dictionary<int, ThermoModels.ModuleBlock> ThermoModuleList = new Dictionary<int, ThermoModels.ModuleBlock>();
|
|
|
|
// Dizionario parametri specifici per THERMO
|
|
private static Dictionary<int, ThermoModels.RecipeParam> ThermoParamList = new Dictionary<int, ThermoModels.RecipeParam>();
|
|
|
|
private static ThermoModels.ProdCycleModel ThermoProdCycle = new ThermoModels.ProdCycleModel();
|
|
private static ThermoModels.ProdInfoModel ThermoProdInfo = new ThermoModels.ProdInfoModel();
|
|
private static Dictionary<int, ThermoModels.WarmerChannel> ThermoWarmChannels = new Dictionary<int, ThermoModels.WarmerChannel>();
|
|
private static string UnitOfMeasure;
|
|
private bool EnableAlarms;
|
|
private bool EnableAxes;
|
|
private bool EnableHeaters;
|
|
private bool EnableModules;
|
|
private bool EnableParameters;
|
|
private bool EnableProd;
|
|
private short rack = 0;
|
|
private byte S7Language;
|
|
private short slot = 1;
|
|
|
|
// connessione S7
|
|
private CpuType tipoCpu = CpuType.S71500;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Oggetto PLC da ri-utilizzare...
|
|
/// </summary>
|
|
protected Plc currPLC;
|
|
|
|
#endregion Protected Fields
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#region Public Constructors
|
|
|
|
///<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)
|
|
{
|
|
initObjects(IpAddress, RemotePort, false, true, true, true, true, true);
|
|
}
|
|
|
|
/// <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)
|
|
{
|
|
initObjects(IpAddress, RemotePort, EnableAxes, EnableAlarms, EnableHeaters, EnableModules, EnableParameters, EnableProd);
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Methods
|
|
|
|
private Dictionary<string, double> AXES_RAxesPos(ushort channel, string positionType)
|
|
{
|
|
Dictionary<string, double> axes = new Dictionary<string, double>();
|
|
return axes;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
//Check Bit In Range
|
|
private CmsError CheckBitRange(int bitnum)
|
|
{
|
|
if (bitnum < 0 || bitnum > 7)
|
|
return BIT_NOT_IN_RANGE_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Check if NC is connected
|
|
private CmsError CheckConnection()
|
|
{
|
|
if (!NC_IsConnected())
|
|
return NOT_CONNECTED_ERROR;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <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;
|
|
}
|
|
|
|
// Check if Memory Area is corrected
|
|
private CmsError ConvertMemToPath(MEMORY_TYPE MemoryType, int Address, int SubAddress, int SubBit, int Qty, char MemAccess, out string item)
|
|
{
|
|
char[] allowedAccess = { 'X', 'B', 'W', 'D' };
|
|
|
|
//Check if is the right area and allowed type
|
|
if (!MemoryType.ToString().StartsWith(SIEMENS_MEMTYPE) || !allowedAccess.Contains(MemAccess) || Qty < 1)
|
|
{
|
|
item = "";
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
//If is Bit Access change access type
|
|
if (MemAccess == 'X')
|
|
item = "DB" + Address + ".DB" + MemAccess + SubAddress + "." + SubBit;
|
|
else
|
|
item = "DB" + Address + ".DB" + MemAccess + SubAddress + "[" + Qty + "]";
|
|
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
|
|
private string ConvertStepToSiemensScreen(SCREEN_PAGE page)
|
|
{
|
|
switch (page)
|
|
{
|
|
case SCREEN_PAGE.Siemens_Machine: return "AreaMachine";
|
|
case SCREEN_PAGE.Siemens_Parameter: return "AreaParameter";
|
|
case SCREEN_PAGE.Siemens_Program: return "AreaProgramEdit";
|
|
case SCREEN_PAGE.Siemens_ProgramManager: return "AreaProgramManager";
|
|
case SCREEN_PAGE.Siemens_Setup: return "AreaStartup";
|
|
case SCREEN_PAGE.Siemens_Diagnostics: return "AreaDiagnosis";
|
|
default: return "";
|
|
}
|
|
}
|
|
|
|
//Convert to Step Language
|
|
private string ConvertToNCLanguage(CultureInfo language)
|
|
{
|
|
return language.ThreeLetterISOLanguageName;
|
|
}
|
|
|
|
//Convert to Step Language
|
|
private CultureInfo ConvertToSTEPLanguage(uint language)
|
|
{
|
|
switch (language)
|
|
{
|
|
case 1: return new CultureInfo("de");
|
|
case 2: return new CultureInfo("fr");
|
|
case 3: return new CultureInfo("en");
|
|
case 4: return new CultureInfo("es");
|
|
case 6: return new CultureInfo("it");
|
|
case 7: return new CultureInfo("nl");
|
|
case 8: return new CultureInfo("zh-CHS");
|
|
case 9: return new CultureInfo("sv");
|
|
case 18: return new CultureInfo("hu");
|
|
case 19: return new CultureInfo("fi");
|
|
case 26: return new CultureInfo("el");
|
|
case 28: return new CultureInfo("cs");
|
|
case 50: return new CultureInfo("pt-BR");
|
|
case 53: return new CultureInfo("pl");
|
|
case 55: return new CultureInfo("da");
|
|
case 57: return new CultureInfo("ru");
|
|
case 65: return new CultureInfo("hr-HR");
|
|
case 68: return new CultureInfo("sk");
|
|
case 69: return new CultureInfo("sl");
|
|
case 72: return new CultureInfo("ro");
|
|
case 75: return new CultureInfo("bg");
|
|
case 80: return new CultureInfo("zh-CHT");
|
|
case 85: return new CultureInfo("ko");
|
|
case 87: return new CultureInfo("ja");
|
|
case 89: return new CultureInfo("tr");
|
|
case 122: return new CultureInfo("id");
|
|
case 212: return new CultureInfo("th");
|
|
case 213: return new CultureInfo("vi");
|
|
case 230: return new CultureInfo("ms");
|
|
default: return new CultureInfo("en");
|
|
}
|
|
}
|
|
|
|
//Manage the Mode
|
|
private PROC_MODE ConvertToSTEPMode(uint mode, uint JogMode, uint AdvMode)
|
|
{
|
|
if (mode == 0)
|
|
{
|
|
if (AdvMode == 0)
|
|
return (JogMode < 6) ? PROC_MODE.JOGINC : PROC_MODE.JOG;
|
|
else if (AdvMode == 1)
|
|
return PROC_MODE.RETPROF;
|
|
else if (AdvMode == 2)
|
|
return PROC_MODE.TEACH;
|
|
else if (AdvMode == 3)
|
|
return PROC_MODE.REF;
|
|
}
|
|
else if (mode == 1)
|
|
return PROC_MODE.MDI;
|
|
else if (mode == 2)
|
|
return PROC_MODE.AUTO;
|
|
|
|
return PROC_MODE.ERROR;
|
|
}
|
|
|
|
//Manage the Status
|
|
private PROC_STATUS ConvertToSTEPStatus(uint status)
|
|
{
|
|
switch (status)
|
|
{
|
|
case 0: return PROC_STATUS.IDLE;
|
|
case 1: return PROC_STATUS.RUN;
|
|
case 2: return PROC_STATUS.HOLD;
|
|
}
|
|
return PROC_STATUS.ERROR;
|
|
}
|
|
|
|
private string FormatPath(string path)
|
|
{
|
|
path = path.TrimStart('\\');
|
|
path = path.TrimStart('/');
|
|
path = path.TrimEnd('\\');
|
|
|
|
return path.Replace('\\', '/');
|
|
}
|
|
|
|
// Create and return CmsError object
|
|
private CmsError GetError(string message)
|
|
{
|
|
return CmsError.NcError(message);
|
|
}
|
|
|
|
private IEnumerable<string> GetLinesFromString(string text)
|
|
{
|
|
string line;
|
|
using (StringReader reader = new StringReader(text))
|
|
{
|
|
while ((line = reader.ReadLine()) != null)
|
|
{
|
|
yield return line;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Convert the internal Name var in Readable STEP Name
|
|
private string GetName(uint value)
|
|
{
|
|
string name = "Siemens ";
|
|
switch (value)
|
|
{
|
|
case 0: name += "840D pl"; break;
|
|
case 1000: name += "FM-NC"; break;
|
|
case 2000: name += "810D pl"; break;
|
|
case 3000: name += "802S"; break;
|
|
case 4000: name += "802D pl"; break;
|
|
case 5000: name += "840Di pl"; break;
|
|
case 6000: name += "SOLUTIONLINE"; break;
|
|
case 10700: name += "840D sl"; break;
|
|
case 14000: name += "802D sl T/M - N/G - C/U"; break;
|
|
case 15000: name += "840Di sl"; break;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
/// <summary>
|
|
/// /Inizializzazione effettiva parametri classe
|
|
/// </summary>
|
|
/// <param name="IpAddress"></param>
|
|
/// <param name="RemotePort"></param>
|
|
/// <param name="EnableAxes"></param>
|
|
/// <param name="EnableAlarms"></param>
|
|
/// <param name="EnableHeaters"></param>
|
|
/// <param name="EnableModules"></param>
|
|
/// <param name="EnableParameters"></param>
|
|
/// <param name="EnableProd"></param>
|
|
private void initObjects(string IpAddress, ushort RemotePort, 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>();
|
|
// Init dati specifici Thermo
|
|
}
|
|
|
|
//Manage the Exception Launch
|
|
private CmsError ManageException(Exception ex)
|
|
{
|
|
// Catch the S7Net exceptions
|
|
if (ex.Message.Contains(NcNotFound) || ex.Message.Contains(NcNotFound2) || ex.Message.Contains(NcNotFound3) || ex.Message.Contains("Read() failed:"))
|
|
{
|
|
Connected = false;
|
|
return NOT_CONNECTED_ERROR;
|
|
}
|
|
else
|
|
{
|
|
return CmsError.InternalError(ex.Message, ex);
|
|
}
|
|
}
|
|
|
|
private void NcLanguageChanged(string language)
|
|
{
|
|
}
|
|
|
|
private CmsError PLC_ManageActiveAck(int strobeByte, int strobeSubByte, int strobeBit, int ackByte, int ackSubByte, int ackBit, MEMORY_TYPE memType, bool fixEndian)
|
|
{
|
|
int n = 1200; // 30 seconds
|
|
bool readValue = false;
|
|
bool writeValue = true;
|
|
bool ok = false;
|
|
// Set ack to 1
|
|
CmsError libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
do
|
|
{
|
|
// Check strobe
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, strobeByte, strobeSubByte, strobeBit, ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// If true reset acknowledge
|
|
if (!readValue)
|
|
{
|
|
writeValue = false;
|
|
// Reset acknowledge
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// Exit from cycle
|
|
n = 0;
|
|
ok = true;
|
|
}
|
|
else
|
|
{
|
|
// Decrement
|
|
n--;
|
|
// Wait befor next cycle
|
|
Thread.Sleep(25);
|
|
}
|
|
} while (n > 0);
|
|
|
|
// If loop timeout goes in timeout
|
|
if (!ok)
|
|
{
|
|
// Reset acknowledge
|
|
writeValue = false;
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, ackByte, ackSubByte, ackBit, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
private CmsError PLC_RSoftKeys(MEMORY_CELL softKeyStatusMemory, MEMORY_CELL softKeysClickableMemory, ref List<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 libraryError = MEM_RWIntegerList(R, 0,
|
|
softKeyStatusMemory.MemType,
|
|
softKeyStatusMemory.Address,
|
|
softKeyStatusMemory.SubAddress,
|
|
memorySizeToRead / 4,
|
|
ref readValues);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// need byte swap!
|
|
List<int> fixValues = new List<int>();
|
|
foreach (var item in readValues)
|
|
{
|
|
fixValues.Add(SwapBytes(item));
|
|
}
|
|
// Convert ints into an array of bools
|
|
bool[] bits = IntToBits(fixValues.ToArray());
|
|
|
|
// Convert array into structured data
|
|
for (ushort i = 0; i < bits.Count() / 2; i++)
|
|
{
|
|
softKeys.Add(new SoftKeysModel()
|
|
{
|
|
Id = (uint)i + 1,
|
|
Value = bits[i],
|
|
Active = bits[i + offset]
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write ack for strobe received from PLC
|
|
/// </summary>
|
|
/// <param name="fixEndian">Apply endianness swap (word=yes, bitArray=no)</param>
|
|
/// <param name="ackCell"></param>
|
|
/// <param name="strobeCell"></param>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
private CmsError PLC_WAck(bool fixEndian, MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id)
|
|
{
|
|
CmsError libraryError;
|
|
bool readValue = false;
|
|
bool writeValue = true;
|
|
|
|
SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId);
|
|
|
|
// Check Strobe
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// if there's a strobe --> give ack!!!
|
|
if (readValue)
|
|
{
|
|
// abbasso ack se fosse su...
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// attendo 50ms...
|
|
Thread.Sleep(50);
|
|
|
|
// Reset wait ack = 1 and reset the strobe
|
|
libraryError = ResetAck(alarmBitId, strobeByte, ackByte, ackCell.MemType, ackCell.Address, fixEndian);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// exit and next round will continue...
|
|
return NO_ERROR;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write strobe and manage ack from PLC
|
|
/// </summary>
|
|
/// <param name="fixEndian">Apply endianness swap (word=yes, bitArray=no)</param>
|
|
/// <param name="ackCell"></param>
|
|
/// <param name="strobeCell"></param>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
private CmsError PLC_WStrobe(bool fixEndian, MEMORY_CELL ackCell, MEMORY_CELL strobeCell, uint id)
|
|
{
|
|
CmsError libraryError;
|
|
bool readValue = false;
|
|
bool writeValue = true;
|
|
|
|
SetupAckStrobeAddresses(ackCell.SubAddress, strobeCell.SubAddress, id, out int ackByte, out int strobeByte, out int alarmBitId);
|
|
|
|
// Check Strobe
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// se è true
|
|
int n = 200;
|
|
do
|
|
{
|
|
// Check Strobe
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref readValue);
|
|
Thread.Sleep(20);
|
|
n--;
|
|
} while (n > 0 && readValue);
|
|
|
|
// If PLC is true --> reset
|
|
if (readValue)
|
|
{
|
|
bool forceVal = false;
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref forceVal);
|
|
}
|
|
|
|
// Check ACK
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, ackCell.MemType, ackCell.Address, ackByte, alarmBitId, ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// If PLC it's performing another request then return
|
|
if (readValue)
|
|
return NO_ERROR;
|
|
|
|
// Write strobe into memory
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, strobeCell.MemType, strobeCell.Address, strobeByte, alarmBitId, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Reset wait ack = 1 and reset the strobe
|
|
libraryError = ResetStrobe(alarmBitId, strobeByte, ackByte, ackCell.MemType, ackCell.Address, fixEndian);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
private bool PositionContainsTool(MountedToolModel mounted, int toolId)
|
|
{
|
|
if (mounted.ToolId == toolId)
|
|
return true;
|
|
//else
|
|
//{
|
|
// // Check if tool is a multitool child
|
|
// foreach (var multi in MultitoolsData)
|
|
// {
|
|
// // Check childs id
|
|
// int index = multi.ChildsTools.FindIndex(x => x.Id == toolId);
|
|
// if (index >= 0)
|
|
// return true;
|
|
// }
|
|
//}
|
|
|
|
return false;
|
|
}
|
|
|
|
private CmsError PROC_ReadActiveLine(uint processId, ref string line)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
//Read Static Data
|
|
private CmsError ReadStaticNCData()
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
#if false
|
|
// prendo 2° valore(num max valori)
|
|
numByte = memByteRead[1];
|
|
// poi prendo la stringa...
|
|
string outVal = "";
|
|
for (int i = 2; i < numByte + 2; i++)
|
|
{
|
|
outVal += Char.ConvertFromUtf32(memByteRead[i]);
|
|
}
|
|
#endif
|
|
|
|
// Read oly one time every X seconds
|
|
if (DateTime.Now - Last_Static_Read > new TimeSpan(NC_MIN_SEC_READ_STATIC_DATA * TimeSpan.TicksPerSecond))
|
|
{
|
|
//Try to get information
|
|
try
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
libraryError = MEM_RWByteList(R, 0, STATIC_DATA.MemType, STATIC_DATA.Address, STATIC_DATA.SubAddress, 0, STATIC_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (currMem.Count > 0)
|
|
{
|
|
// completare nuove variabili (matricola macchina, seriale PLC, firmware PLC)
|
|
S7Language = 0;
|
|
ConfChannelNo = 1;
|
|
Last_Static_Read = DateTime.Now;
|
|
Cnc_name = $"{currPLC.CPU}";
|
|
// decodifico info!
|
|
byte[] memByteRead = currMem.Skip(0).Take(4).ToArray();
|
|
int numByte = 0;
|
|
string outVal = "";
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
outVal += Char.ConvertFromUtf32(memByteRead[i]);
|
|
}
|
|
Cms_MachNumber = outVal; // matricola macchina, DB604.DBB6720..6723
|
|
|
|
memByteRead = currMem.Skip(4).Take(22).ToArray();
|
|
outVal = "";
|
|
numByte = memByteRead[1];
|
|
for (int i = 2; i < numByte + 2; i++)
|
|
{
|
|
outVal += Char.ConvertFromUtf32(memByteRead[i]);
|
|
}
|
|
Cnc_SftVersion = outVal; // versione SW del firmware PLC/CNC | DB604.DBB6724..6745
|
|
|
|
memByteRead = currMem.Skip(26).Take(18).ToArray();
|
|
outVal = "";
|
|
numByte = memByteRead[1];
|
|
for (int i = 2; i < numByte + 2; i++)
|
|
{
|
|
outVal += Char.ConvertFromUtf32(memByteRead[i]);
|
|
}
|
|
Cnc_SeriesNum = outVal; // seriale PLC/CNC | DB604.DBB6746..6763
|
|
|
|
memByteRead = currMem.Skip(44).Take(4).ToArray();
|
|
outVal = "";
|
|
outVal += Char.ConvertFromUtf32(memByteRead[0]);
|
|
for (int i = 1; i < 4; i++)
|
|
{
|
|
outVal += $"{memByteRead[i]}";
|
|
}
|
|
PlcFirmware_SerialNum = outVal; // seriale PLC/CNC | DB604.DBB6764..6767
|
|
|
|
UnitOfMeasure = MILLIMETERS;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Canali Riscaldi: actual current PLC
|
|
/// </summary>
|
|
private void refreshRiscActCurr()
|
|
{
|
|
// leggo DB514 x area Ich
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_ICH_DATA.MemType, RISC_ICH_DATA.Address, RISC_ICH_DATA.SubAddress, 0, RISC_ICH_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
double currVal = 0;
|
|
for (int i = 0; i < RISC_ICH_DATA.Size / 4; i++)
|
|
{
|
|
currVal = S7.Net.Types.Double.FromByteArray(memArray.Skip(4 * i).Take(4).ToArray());
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
ThermoWarmChannels[i + 1].CurrAct = currVal;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
CurrAct = currVal
|
|
});
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Canali Riscaldi: Percentuale lavoro Attuale
|
|
/// </summary>
|
|
private void refreshRiscPerc()
|
|
{
|
|
// leggo DB514 x area OVp
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_OVP_DATA.MemType, RISC_OVP_DATA.Address, RISC_OVP_DATA.SubAddress, 0, RISC_OVP_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < RISC_OVP_DATA.Size; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
ThermoWarmChannels[i + 1].PercAct = memArray[i];
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
PercAct = memArray[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Canali Riscaldi: SetPoint HMI
|
|
/// </summary>
|
|
private void refreshRiscSetpointHMI()
|
|
{
|
|
// leggo DB614 x area Ich
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < RISC_CHP_DATA.Size; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
try
|
|
{
|
|
ThermoWarmChannels[i + 1].SetpointHMI = memArray[i];
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
SetpointHMI = memArray[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Canali Riscaldi: SetPoint PLC (% lavoro applicata ATTUALE dal PLC)
|
|
/// </summary>
|
|
private void refreshRiscSetpointPLC()
|
|
{
|
|
// leggo area DB627 (era DB514) x area CHp
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_PLC_DATA.MemType, RISC_PLC_DATA.Address, RISC_PLC_DATA.SubAddress, 0, RISC_PLC_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < RISC_PLC_DATA.Size; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
ThermoWarmChannels[i + 1].SetpointPLC = memArray[i];
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
SetpointPLC = memArray[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh Canali Riscaldi: Status
|
|
/// </summary>
|
|
private void refreshRiscStatus()
|
|
{
|
|
// leggo DB514 x area ESP
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_ESP_DATA.MemType, RISC_ESP_DATA.Address, RISC_ESP_DATA.SubAddress, 0, RISC_ESP_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < RISC_ESP_DATA.Size; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
ThermoWarmChannels[i + 1].ChStatus = memArray[i];
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
ChStatus = memArray[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh dati ThermoCamera dal PLC x area command/status
|
|
/// </summary>
|
|
private void refreshRiscTermoCamCommStatus()
|
|
{
|
|
#if false
|
|
// leggo DB614 x area Ich
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < RISC_CHP_DATA.Size; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
try
|
|
{
|
|
ThermoWarmChannels[i + 1].SetpointHMI = memArray[i];
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
SetpointHMI = memArray[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh dati ThermoCamera dal PLC x area command/status
|
|
/// </summary>
|
|
private void refreshRiscTermoCamEnab()
|
|
{
|
|
// leggo DB664 x abilitazione ch alla termocamera
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
bool[] bits = new bool[TCAM_CH_ENAB_DATA.Size * 8];
|
|
|
|
// Convert int into to true/false array
|
|
var bArray = new BitArray(currMem.ToArray());
|
|
bArray.CopyTo(bits, 0);
|
|
|
|
for (int i = 0; i < TCAM_CH_ENAB_DATA.Size * 8; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
try
|
|
{
|
|
ThermoWarmChannels[i + 1].TCamActive = bits[i];
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
TCamActive = bits[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh dati ThermoCamera dal PLC: ultima temp letta
|
|
/// </summary>
|
|
private void refreshRiscTermoCamTempAct()
|
|
{
|
|
// leggo DB625 x Temp attuale
|
|
List<short> currMem = new List<short>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_ACT_DATA.MemType, TCAM_TEMP_ACT_DATA.Address, TCAM_TEMP_ACT_DATA.SubAddress, TCAM_TEMP_ACT_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
for (int i = 0; i < TCAM_TEMP_ACT_DATA.Size / 2; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
try
|
|
{
|
|
ThermoWarmChannels[i + 1].TCamTempActual = currMem[i];
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
TCamTempActual = currMem[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh dati ThermoCamera dal PLC: temperatura impostata come riferimento
|
|
/// </summary>
|
|
private void refreshRiscTermoCamTempSet()
|
|
{
|
|
// leggo DB624 x Setpoint Temp richiesti
|
|
List<short> currMem = new List<short>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem);
|
|
|
|
// copio! controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
for (int i = 0; i < TCAM_TEMP_REQ_DATA.Size / 2; i++)
|
|
{
|
|
// cerco id + 1 (su memoria è base 0)
|
|
if (ThermoWarmChannels.ContainsKey(i + 1))
|
|
{
|
|
try
|
|
{
|
|
ThermoWarmChannels[i + 1].TCamTempSet = currMem[i];
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
ThermoWarmChannels.Add(i + 1, new ThermoModels.WarmerChannel()
|
|
{
|
|
IdChannel = i + 1,
|
|
TCamTempSet = currMem[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
}
|
|
|
|
private CmsError ResetAck(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType, int address, bool fixEndian)
|
|
{
|
|
int n = 600;
|
|
bool readValue = false;
|
|
bool writeValue = false;
|
|
bool ok = false;
|
|
|
|
// aspetto 100ms
|
|
Thread.Sleep(100);
|
|
|
|
CmsError libraryError;
|
|
do
|
|
{
|
|
// Check Strobe
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, address, strobeByte, bitId, ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// If false reset ACK
|
|
if (readValue == false)
|
|
{
|
|
// Reset strobe
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, address, ackByte, bitId, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// Exit from cycle
|
|
n = 0;
|
|
ok = true;
|
|
}
|
|
else
|
|
{
|
|
// Decrement
|
|
n--;
|
|
// Wait befor next cycle
|
|
Thread.Sleep(20);
|
|
}
|
|
} while (n > 0);
|
|
|
|
if (!ok)
|
|
{
|
|
// Reset ack (forced)
|
|
writeValue = false;
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, address, ackByte, bitId, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
private CmsError ResetStrobe(int bitId, int strobeByte, int ackByte, MEMORY_TYPE memType, int address, bool fixEndian)
|
|
{
|
|
int n = 200;
|
|
bool readValue = false;
|
|
bool writeValue = false;
|
|
bool ok = false;
|
|
|
|
CmsError libraryError;
|
|
do
|
|
{
|
|
// Check ACK
|
|
libraryError = MEM_RWBoolean(R, fixEndian, 0, memType, address, ackByte, bitId, ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// If true reset strobe
|
|
if (readValue == true)
|
|
{
|
|
// Reset strobe
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, address, strobeByte, bitId, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// Exit from cycle
|
|
n = 0;
|
|
ok = true;
|
|
}
|
|
else
|
|
{
|
|
// Decrement
|
|
n--;
|
|
// Wait befor next cycle
|
|
Thread.Sleep(20);
|
|
}
|
|
} while (n > 0);
|
|
|
|
if (!ok)
|
|
{
|
|
writeValue = false;
|
|
// Reset strobe
|
|
libraryError = MEM_RWBoolean(W, fixEndian, 0, memType, address, strobeByte, bitId, ref writeValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
private int SetBitValue(int intVal, bool val, int bitIndex)
|
|
{
|
|
if (val)
|
|
return intVal | (1 << (bitIndex - 1));
|
|
else
|
|
return intVal & ~(1 << (bitIndex - 1));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setup memory for ack/strobe processing
|
|
/// </summary>
|
|
/// <param name="ackAddress">base addr for ack zone</param>
|
|
/// <param name="strobeAddress">base addr for strobe zone</param>
|
|
/// <param name="id">parameters to set (id 1...n)</param>
|
|
/// <param name="ackByte">ack byte to use (OUT)</param>
|
|
/// <param name="strobeByte">strobe byte to use (out)</param>
|
|
/// <param name="bit">bit 1..8</param>
|
|
private void SetupAckStrobeAddresses(int ackAddress, int strobeAddress, uint id, out int ackByte, out int strobeByte, out int bit)
|
|
{
|
|
ackByte = ackAddress + (((int)id - 1) / 8);
|
|
strobeByte = strobeAddress + (((int)id - 1) / 8);
|
|
bit = (((int)id - 1) % 8);
|
|
}
|
|
|
|
private int SwapIntEndianFormat(int value)
|
|
{
|
|
var b1 = (value >> 0) & 0xff;
|
|
var b2 = (value >> 8) & 0xff;
|
|
var b3 = (value >> 16) & 0xff;
|
|
var b4 = (value >> 24) & 0xff;
|
|
|
|
return b1 << 24 | b2 << 16 | b3 << 8 | b4 << 0;
|
|
}
|
|
|
|
private short SwapShortEndianFormat(short value)
|
|
{
|
|
var b1 = (value >> 0) & 0xff;
|
|
var b2 = (value >> 8) & 0xff;
|
|
|
|
return (short)(b1 << 8 | b2 << 0);
|
|
}
|
|
|
|
private ushort SwapShortEndianFormat(ushort value)
|
|
{
|
|
var b1 = (value >> 0) & 0xff;
|
|
var b2 = (value >> 8) & 0xff;
|
|
|
|
return (ushort)(b1 << 8 | b2 << 0);
|
|
}
|
|
|
|
/// <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;
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Refresh recipe parameters
|
|
/// </summary>
|
|
protected CmsError refreshChIOForced()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<ushort> readValuesDO = new List<ushort>();
|
|
List<ushort> readValuesAO = new List<ushort>();
|
|
|
|
// leggo da PLC a array di byte di appoggio x visibilità DO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref readValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità AO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref readValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoIOFor.DO = convToDictIntBol(readValuesDO);
|
|
ThermoIOFor.AO = convToDictIntBol(readValuesAO);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh recipe parameters
|
|
/// </summary>
|
|
protected CmsError refreshChIOForcedVal()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<ushort> readValuesDO = new List<ushort>();
|
|
List<short> readValuesAO = new List<short>();
|
|
|
|
// leggo da PLC valori DO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DO_VAL_FOR.MemType, IO_DO_VAL_FOR.Address, IO_DO_VAL_FOR.SubAddress, IO_DO_VAL_FOR.Size, ref readValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC valori AO...
|
|
libraryError = MEM_RWShortList(R, 0, IO_AO_VAL_FOR.MemType, IO_AO_VAL_FOR.Address, IO_AO_VAL_FOR.SubAddress, IO_AO_VAL_FOR.Size, ref readValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoIOValFor.DO = convToDictIntBol(readValuesDO);
|
|
ThermoIOValFor.AO = convToDictIntInt(readValuesAO);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh IO channels actual value
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected CmsError refreshChIOVal()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<ushort> readValuesDI = new List<ushort>();
|
|
List<ushort> readValuesDO = new List<ushort>();
|
|
List<short> readValuesAI = new List<short>();
|
|
List<short> readValuesAO = new List<short>();
|
|
|
|
// leggo da PLC a array di byte di appoggio x visibilità DI...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DI_VAL_ACT.MemType, IO_DI_VAL_ACT.Address, IO_DI_VAL_ACT.SubAddress, IO_DI_VAL_ACT.Size, ref readValuesDI);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità DO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DO_VAL_ACT.MemType, IO_DO_VAL_ACT.Address, IO_DO_VAL_ACT.SubAddress, IO_DO_VAL_ACT.Size, ref readValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità AI...
|
|
libraryError = MEM_RWShortList(R, 0, IO_AI_VAL_ACT.MemType, IO_AI_VAL_ACT.Address, IO_AI_VAL_ACT.SubAddress, IO_AI_VAL_ACT.Size, ref readValuesAI);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità AO...
|
|
libraryError = MEM_RWShortList(R, 0, IO_AO_VAL_ACT.MemType, IO_AO_VAL_ACT.Address, IO_AO_VAL_ACT.SubAddress, IO_AO_VAL_ACT.Size, ref readValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoIOVal.DI = convToDictIntBol(readValuesDI);
|
|
ThermoIOVal.DO = convToDictIntBol(readValuesDO);
|
|
ThermoIOVal.AI = convToDictIntInt(readValuesAI);
|
|
ThermoIOVal.AO = convToDictIntInt(readValuesAO);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh recipe parameters
|
|
/// </summary>
|
|
protected CmsError refreshChIOVisib()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<ushort> readValuesDI = new List<ushort>();
|
|
List<ushort> readValuesDO = new List<ushort>();
|
|
List<ushort> readValuesAI = new List<ushort>();
|
|
List<ushort> readValuesAO = new List<ushort>();
|
|
|
|
// leggo da PLC a array di byte di appoggio x visibilità DI...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DI_VISIB.MemType, IO_DI_VISIB.Address, IO_DI_VISIB.SubAddress, IO_DI_VISIB.Size, ref readValuesDI);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità DO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DO_VISIB.MemType, IO_DO_VISIB.Address, IO_DO_VISIB.SubAddress, IO_DO_VISIB.Size, ref readValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità AI...
|
|
libraryError = MEM_RWWordList(R, 0, IO_AI_VISIB.MemType, IO_AI_VISIB.Address, IO_AI_VISIB.SubAddress, IO_AI_VISIB.Size, ref readValuesAI);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// leggo da PLC a array di byte di appoggio x visibilità AO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_AO_VISIB.MemType, IO_AO_VISIB.Address, IO_AO_VISIB.SubAddress, IO_AO_VISIB.Size, ref readValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoIOVis.DI = convToDictIntBol(readValuesDI);
|
|
ThermoIOVis.DO = convToDictIntBol(readValuesDO);
|
|
ThermoIOVis.AI = convToDictIntBol(readValuesAI);
|
|
ThermoIOVis.AO = convToDictIntBol(readValuesAO);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh ModuleBlock
|
|
/// </summary>
|
|
protected void refreshMemModBlockParameter()
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 18;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, MODULE_DATA.MemType, MODULE_DATA.Address, MODULE_DATA.SubAddress, 0, MODULE_DATA.Size, ref currMem);
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < MODULE_DATA.Size / packSize; i++)
|
|
{
|
|
PlcModBlock currModBlock = new PlcModBlock(memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// calcolo lista PrecId
|
|
List<short> PrecId = new List<short>();
|
|
PrecId.Add(currModBlock.PrevId_01);
|
|
PrecId.Add(currModBlock.PrevId_02);
|
|
PrecId.Add(currModBlock.PrevId_03);
|
|
// solo se ID > 0...
|
|
if (currModBlock.Id > 0)
|
|
{
|
|
// update oggetto thermoParamList...
|
|
if (ThermoModuleList.ContainsKey(currModBlock.Id))
|
|
{
|
|
ThermoModuleList[currModBlock.Id].EstimatedDelay = currModBlock.EstimDelay;
|
|
ThermoModuleList[currModBlock.Id].EstimatedDuration = currModBlock.EstimDuration;
|
|
ThermoModuleList[currModBlock.Id].PrecedingId = PrecId;
|
|
}
|
|
else
|
|
{
|
|
ThermoModuleList.Add(currModBlock.Id, new ThermoModels.ModuleBlock()
|
|
{
|
|
Id = currModBlock.Id,
|
|
EstimatedDelay = currModBlock.EstimDelay,
|
|
EstimatedDuration = currModBlock.EstimDuration,
|
|
PrecedingId = PrecId
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_WRONG_DATA;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh ModuleBlock RT
|
|
/// </summary>
|
|
protected void refreshMemModBlockParameterRT()
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 12;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, MODULE_RT_DATA.MemType, MODULE_RT_DATA.Address, MODULE_RT_DATA.SubAddress, 0, MODULE_RT_DATA.Size, ref currMem);
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < MODULE_RT_DATA.Size / packSize; i++)
|
|
{
|
|
PlcModBlockRT currModBlock = new PlcModBlockRT(memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// solo se ID > 0...
|
|
if (currModBlock.Id > 0)
|
|
{
|
|
// update oggetto thermoParamList...
|
|
if (ThermoModuleList.ContainsKey(currModBlock.Id))
|
|
{
|
|
try
|
|
{
|
|
ThermoModuleList[currModBlock.Id].Visible = currModBlock.Visible;
|
|
ThermoModuleList[currModBlock.Id].Running = currModBlock.Running;
|
|
ThermoModuleList[currModBlock.Id].HasError = currModBlock.HasError;
|
|
ThermoModuleList[currModBlock.Id].Terminated = currModBlock.Terminated;
|
|
ThermoModuleList[currModBlock.Id].ActualDuration = currModBlock.ActualDuration;
|
|
ThermoModuleList[currModBlock.Id].ActualDelay = currModBlock.ActualDelay;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
ThermoModuleList.Add(currModBlock.Id, new ThermoModels.ModuleBlock()
|
|
{
|
|
Id = currModBlock.Id,
|
|
ActualDuration = currModBlock.ActualDuration,
|
|
ActualDelay = currModBlock.ActualDelay,
|
|
Visible = currModBlock.Visible,
|
|
Running = currModBlock.Running,
|
|
HasError = currModBlock.HasError,
|
|
Terminated = currModBlock.Terminated
|
|
});
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_WRONG_DATA;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh recipe parameters
|
|
/// </summary>
|
|
protected CmsError refreshMemRecipeParameter()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 20;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
libraryError = MEM_RWByteList(R, 0, PARAMETER_DATA.MemType, PARAMETER_DATA.Address, PARAMETER_DATA.SubAddress, 0, PARAMETER_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
|
|
for (int i = 0; i < PARAMETER_DATA.Size / packSize; i++)
|
|
{
|
|
PlcParam currParam = new PlcParam(memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// solo se ID > 0...
|
|
if (currParam.Id > 0)
|
|
{
|
|
// update oggetto thermoParamList...
|
|
if (ThermoParamList.ContainsKey(currParam.Id))
|
|
{
|
|
try
|
|
{
|
|
ThermoParamList[currParam.Id].SetpointHMI = currParam.SetpointHMI;
|
|
ThermoParamList[currParam.Id].SetpointPLC = currParam.SetpointPLC;
|
|
ThermoParamList[currParam.Id].ValMax = currParam.ValMax;
|
|
ThermoParamList[currParam.Id].ValMin = currParam.ValMin;
|
|
ThermoParamList[currParam.Id].UnitMeasure = currParam.UnitMeasure;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
ThermoParamList.Add(currParam.Id, new ThermoModels.RecipeParam() { Id = currParam.Id, SetpointHMI = currParam.SetpointHMI, SetpointPLC = currParam.SetpointPLC, ValMax = currParam.ValMax, ValMin = currParam.ValMin, UnitMeasure = currParam.UnitMeasure });
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_WRONG_DATA;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
libraryError = S7_PLC_EMPTY_READ;
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refresh recipE parameters RT
|
|
/// </summary>
|
|
protected CmsError refreshMemRecipeParameterRT()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 8;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
libraryError = MEM_RWByteList(R, 0, PARAMETER_RT_DATA.MemType, PARAMETER_RT_DATA.Address, PARAMETER_RT_DATA.SubAddress, 0, PARAMETER_RT_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di 8 byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < PARAMETER_RT_DATA.Size / packSize; i++)
|
|
{
|
|
PlcParamRT currParam = new PlcParamRT(memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// solo se ID > 0...
|
|
if (currParam.Id > 0)
|
|
{
|
|
// update oggetto thermoParamList...
|
|
if (ThermoParamList.ContainsKey(currParam.Id))
|
|
{
|
|
try
|
|
{
|
|
ThermoParamList[currParam.Id].Enabled = currParam.Enabled;
|
|
ThermoParamList[currParam.Id].HasError = currParam.HasError;
|
|
ThermoParamList[currParam.Id].Visible = currParam.Visible;
|
|
ThermoParamList[currParam.Id].ValueAct = currParam.ValueAct;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
ThermoParamList.Add(currParam.Id, new ThermoModels.RecipeParam() { Id = currParam.Id, Enabled = currParam.Enabled, HasError = currParam.HasError, Visible = currParam.Visible, ValueAct = currParam.ValueAct });
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Public Methods
|
|
|
|
public static byte[] boolsToByteArray(bool[] bits)
|
|
{
|
|
// pack (in this case, using the first bool as the lsb - if you want
|
|
// the first bool as the msb, reverse things ;-p)
|
|
int bytes = bits.Length / 8;
|
|
if ((bits.Length % 8) != 0) bytes++;
|
|
byte[] answ = new byte[bytes];
|
|
int bitIndex = 0, byteIndex = 0;
|
|
for (int i = 0; i < bits.Length; i++)
|
|
{
|
|
if (bits[i])
|
|
{
|
|
answ[byteIndex] |= (byte)(((byte)1) << bitIndex);
|
|
}
|
|
bitIndex++;
|
|
if (bitIndex == 8)
|
|
{
|
|
bitIndex = 0;
|
|
byteIndex++;
|
|
}
|
|
}
|
|
|
|
return answ;
|
|
}
|
|
|
|
public override CmsError AXES_RAxesNames(ushort channel, ref List<AxisModel> axesData)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RDistanceToGo(ushort channel, ref Dictionary<string, double> axes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RFollowingError(ushort channel, ref Dictionary<string, double> axes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RInterpPosition(ushort channel, ref Dictionary<string, double> axes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RMachinePosition(ushort channel, ref Dictionary<string, double> axes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_ROrigin(int numberOfAxes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RProgrPosition(ushort channel, ref Dictionary<string, double> axes)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_RSelectedAxis(ref byte axisId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError AXES_WSelectAxis(byte axisId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_CopyProgram(string partProgramPath, string newPartProgramPath, bool failIfExist)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_DeleteProgram(string partProgramPath, string partProgramName)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <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;
|
|
}
|
|
|
|
public override CmsError FILES_RActiveProgramData(int processId, ref ActiveProgramDataModel programData)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <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;
|
|
}
|
|
|
|
public override CmsError FILES_RGetFileInfo(string path, ref InfoFile fileInfo)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RGetFileList(string path, ref List<PreviewFileModel> files)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RGetProgramType(ref PROGRAM_TYPE_ENUM programType)
|
|
{
|
|
programType = PROGRAM_TYPE_ENUM.PART_PROGRAM;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RProgramToFile(string partProgramPath, FileStream localFile)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RQueueData(ref List<QueueStatusModel> statusList)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_RQueueDataByProcess(ref QueueStatusModel status, int processId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_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_UploadPartProgram(string localPath, string name, ref string newFilePath)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WCleanUploadFolder()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WDeactivateProgram(int processId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WLoadNextPartProgram(string localPath, string ncFileName)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WProgramFromFile(string partProgramPath, FileStream localFile)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WSetActiveProgram(int processId, string filePath, ref ActiveProgramDataModel data)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WStartQueue()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WStopQueue()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WUploadCustomMainProgramAndActivate(int processId, string customPartProgramContent, ref ActiveProgramDataModel activeData)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError FILES_WUploadJobFilesAndActivate(int processId, string jobExtractedPath, string fileToActivate)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
//Read-Write a Boolean-Value inside the NC.
|
|
public override CmsError MEM_RWBoolean(bool bWrite, bool fixEndian, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemBit, ref bool Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
//Check if the Bit Number is Correct
|
|
libraryError = CheckBitRange(MemBit);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
byte bValue = 0;
|
|
ushort pow = (ushort)Math.Pow(2, MemBit);
|
|
|
|
//Read the Byte where is the bit
|
|
libraryError = MEM_RWByte(R, fixEndian, Process, MemType, MemTable, MemIndex, 0, ref bValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
//If i have to Write -> Write the Bit
|
|
if (bWrite)
|
|
{
|
|
if (Value)
|
|
bValue = (byte)(bValue | (1 << MemBit));
|
|
else
|
|
bValue = (byte)(bValue & ~(1 << MemBit));
|
|
|
|
libraryError = MEM_RWByte(W, fixEndian, Process, MemType, MemTable, MemIndex, 0, ref bValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
//If i have to read -> Read the Bit
|
|
else
|
|
{
|
|
Value = (bValue & pow) == pow;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/// <summary>
|
|
/// Read-Write a SINGLE Byte inside the NC. In writing-mode the field "Number" is not required
|
|
/// </summary>
|
|
/// <param name="bWrite">R/W mode</param>
|
|
/// <param name="fixEndian">fix endianness</param>
|
|
/// <param name="Process"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="MemTable"></param>
|
|
/// <param name="MemIndex"></param>
|
|
/// <param name="MemByte"></param>
|
|
/// <param name="Value"></param>
|
|
/// <returns></returns>
|
|
public override CmsError MEM_RWByte(bool bWrite, bool fixEndian, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByte, ref byte Value)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
// attenzione endianness! inverte byte se richiesto...
|
|
int fixIndex = MemIndex;
|
|
if (fixEndian)
|
|
{
|
|
fixIndex = MemIndex % 2 == 0 ? MemIndex + 1 : MemIndex - 1;
|
|
}
|
|
|
|
// vere operazioni R/W
|
|
if (bWrite)
|
|
{
|
|
// try/catch
|
|
try
|
|
{
|
|
byte[] DB_Byte = new byte[1];
|
|
DB_Byte[0] = Value;
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, fixIndex, DB_Byte);
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_BYTE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
var memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, fixIndex, 1);
|
|
Value = memByteRead[0];
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_BYTE;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWByteList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int MemByteStart, int Number, ref List<byte> Values)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
if (bWrite)
|
|
{
|
|
//Prevent some exceptions
|
|
if (Values.Count == 0)
|
|
return NO_ERROR;
|
|
// try/catch
|
|
try
|
|
{
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, Values.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_LST_BYTE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Prevent some exceptions
|
|
if (Number == 0)
|
|
return NO_ERROR;
|
|
Values.Clear();
|
|
try
|
|
{
|
|
byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
|
|
Values = memByteRead.ToList();
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_LST_BYTE;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWDouble(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref double Value)
|
|
{
|
|
List<double> ListValue = new List<double>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError libraryError = MEM_RWDoubleList(bWrite, Process, MemType, MemTable, MemIndex, 4, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWDoubleList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<double> Values)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
if (bWrite)
|
|
{
|
|
//Prevent some exceptions
|
|
if (Values.Count == 0)
|
|
return NO_ERROR;
|
|
|
|
byte[] singleItem = new byte[4];
|
|
List<Byte> memByteList = new List<byte>();
|
|
|
|
foreach (var Item in Values)
|
|
{
|
|
singleItem = S7.Net.Types.Double.ToByteArray(Item);
|
|
memByteList.AddRange(singleItem);
|
|
}
|
|
|
|
try
|
|
{
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_LST_DOUBLE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Prevent some exceptions
|
|
if (Number == 0)
|
|
return NO_ERROR;
|
|
|
|
Values.Clear();
|
|
|
|
try
|
|
{
|
|
byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
|
|
// converto a word!
|
|
double shortVal = 0;
|
|
for (int i = 0; i < memByteRead.Length / 4; i++)
|
|
{
|
|
shortVal = S7.Net.Types.Double.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray());
|
|
Values.Add(shortVal);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_LST_DOUBLE;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWDWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref uint Value)
|
|
{
|
|
List<uint> ListValue = new List<uint>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError libraryError = MEM_RWDWordList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWDWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<uint> Values)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
if (bWrite)
|
|
{
|
|
//Prevent some exceptions
|
|
if (Values.Count == 0)
|
|
return NO_ERROR;
|
|
|
|
byte[] singleItem = new byte[4];
|
|
List<Byte> memByteList = new List<byte>();
|
|
|
|
foreach (var Item in Values)
|
|
{
|
|
singleItem = S7.Net.Types.DWord.ToByteArray(Item);
|
|
memByteList.AddRange(singleItem);
|
|
}
|
|
|
|
try
|
|
{
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_LST_DWORD;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Prevent some exceptions
|
|
if (Number == 0)
|
|
return NO_ERROR;
|
|
|
|
Values.Clear();
|
|
|
|
try
|
|
{
|
|
byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
|
|
// converto a word!
|
|
uint shortVal = 0;
|
|
for (int i = 0; i < memByteRead.Length / 4; i++)
|
|
{
|
|
shortVal = S7.Net.Types.DWord.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray());
|
|
Values.Add(shortVal);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_LST_DWORD;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//Write a Int-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWInteger(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref int Value)
|
|
{
|
|
List<int> ListValue = new List<int>() { Value };
|
|
|
|
// uses the List method with one-element list, reading int32 (4byte) data...
|
|
CmsError libraryError = MEM_RWIntegerList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
if (ListValue.Count > 0)
|
|
{
|
|
Value = ListValue.First();
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lettura lista di interi
|
|
/// </summary>
|
|
/// <param name="bWrite"></param>
|
|
/// <param name="Process"></param>
|
|
/// <param name="MemType"></param>
|
|
/// <param name="MemTable"></param>
|
|
/// <param name="MemIndex"></param>
|
|
/// <param name="Number">numero di INT 32 da leggere (byte/4)</param>
|
|
/// <param name="Values"></param>
|
|
/// <returns></returns>
|
|
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 libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
if (bWrite)
|
|
{
|
|
//Prevent some exceptions
|
|
if (Values.Count == 0)
|
|
return NO_ERROR;
|
|
|
|
byte[] singleItem = new byte[4];
|
|
List<Byte> memByteList = new List<byte>();
|
|
|
|
foreach (var Item in Values)
|
|
{
|
|
singleItem = S7.Net.Types.DInt.ToByteArray(Item);
|
|
memByteList.AddRange(singleItem);
|
|
}
|
|
try
|
|
{
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_LST_INT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Prevent some exceptions
|
|
if (Number == 0)
|
|
return NO_ERROR;
|
|
|
|
Values.Clear();
|
|
byte[] memByteRead = null;
|
|
try
|
|
{
|
|
memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number * 4);
|
|
// converto a word!
|
|
int intVal = 0;
|
|
for (int i = 0; i < memByteRead.Length / 4; i++)
|
|
{
|
|
intVal = S7.Net.Types.DInt.FromByteArray(memByteRead.Skip(4 * i).Take(4).ToArray());
|
|
Values.Add(intVal);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_LST_INT;
|
|
}
|
|
}
|
|
|
|
if (Values.Count == 0)
|
|
{
|
|
return NOT_CONNECTED_ERROR;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWShort(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref short Value)
|
|
{
|
|
List<short> ListValue = new List<short>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError libraryError = MEM_RWShortList(bWrite, Process, MemType, MemTable, MemIndex, 1, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError MEM_RWShortList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<short> Values)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
if (bWrite)
|
|
{
|
|
//Prevent some exceptions
|
|
if (Values.Count == 0)
|
|
return NO_ERROR;
|
|
|
|
byte[] singleItem = new byte[2];
|
|
List<Byte> memByteList = new List<byte>();
|
|
|
|
foreach (var Item in Values)
|
|
{
|
|
singleItem = S7.Net.Types.Int.ToByteArray(Item);
|
|
memByteList.AddRange(singleItem);
|
|
}
|
|
try
|
|
{
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_LST_SHORT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Prevent some exceptions
|
|
if (Number == 0)
|
|
return NO_ERROR;
|
|
|
|
Values.Clear();
|
|
try
|
|
{
|
|
byte[] memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
|
|
// converto a word!
|
|
short shortVal = 0;
|
|
for (int i = 0; i < memByteRead.Length / 2; i++)
|
|
{
|
|
shortVal = S7.Net.Types.Int.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray());
|
|
Values.Add(shortVal);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_LST_SHORT;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//Write a Word-Value inside the NC. In writing-mode the field "Number" is not required
|
|
public override CmsError MEM_RWWord(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, ref ushort Value)
|
|
{
|
|
List<ushort> ListValue = new List<ushort>() { Value };
|
|
|
|
//uses the List method with one-element list
|
|
CmsError libraryError = MEM_RWWordList(bWrite, Process, MemType, MemTable, MemIndex, 2, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
if (ListValue.Count > 0)
|
|
Value = ListValue.First();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
public override CmsError MEM_RWWordList(bool bWrite, int Process, MEMORY_TYPE MemType, int MemTable, int MemIndex, int Number, ref List<ushort> Values)
|
|
{
|
|
////Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (MemType != MEMORY_TYPE.Siemens_DB)
|
|
{
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
}
|
|
|
|
libraryError = null;
|
|
|
|
if (bWrite)
|
|
{
|
|
//Prevent some exceptions
|
|
if (Values.Count == 0)
|
|
return NO_ERROR;
|
|
|
|
byte[] singleItem = new byte[2];
|
|
List<Byte> memByteList = new List<byte>();
|
|
|
|
foreach (var Item in Values)
|
|
{
|
|
singleItem = S7.Net.Types.Word.ToByteArray(Item);
|
|
memByteList.AddRange(singleItem);
|
|
}
|
|
try
|
|
{
|
|
currPLC.WriteBytes(DataType.DataBlock, MemTable, MemIndex, memByteList.ToArray());
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_WRITE_ERROR_LST_WORD;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Prevent some exceptions
|
|
if (Number == 0)
|
|
return NO_ERROR;
|
|
|
|
Values.Clear();
|
|
byte[] memByteRead;
|
|
try
|
|
{
|
|
memByteRead = currPLC.ReadBytes(DataType.DataBlock, MemTable, MemIndex, Number);
|
|
// converto a word!
|
|
ushort shortVal = 0;
|
|
for (int i = 0; i < memByteRead.Length / 2; i++)
|
|
{
|
|
shortVal = S7.Net.Types.Word.FromByteArray(memByteRead.Skip(2 * i).Take(2).ToArray());
|
|
Values.Add(shortVal);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return S7_PLC_READ_ERROR_LST_WORD;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connessione al PLC
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError NC_Connect()
|
|
{
|
|
lock (connectLock)
|
|
{
|
|
// Try to get information
|
|
try
|
|
{
|
|
// Check if Siemens Environment is started
|
|
CmsError libraryError = CheckS7Ping();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Check connection
|
|
currPLC = new Plc(tipoCpu, this.Ip, this.rack, this.slot);
|
|
currPLC.Open();
|
|
if (currPLC.IsConnected)
|
|
Connected = true;
|
|
|
|
// FARE TODO FIXME
|
|
// 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disconnect Method
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError NC_Disconnect()
|
|
{
|
|
// Set Connected to FALSE and close the sessions
|
|
Connected = false;
|
|
if (currPLC != null)
|
|
{
|
|
try
|
|
{
|
|
currPLC.Close();
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco lingue disponibili
|
|
/// </summary>
|
|
/// <param name="languages"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_GetAvailableLanguages(ref ICollection<CultureInfo> languages)
|
|
{
|
|
// FIXME TODO
|
|
#if false
|
|
try
|
|
{
|
|
foreach (string file in Directory.GetFiles(PLC_MESSAGES_FILE_PATH))
|
|
{
|
|
if (Path.GetExtension(file) == ".ts")
|
|
{
|
|
string fileName = Path.GetFileNameWithoutExtension(file);
|
|
|
|
var splittedFileName = fileName.Split('_');
|
|
if (splittedFileName.Count() == 2)
|
|
{
|
|
if (splittedFileName[0].ToLower() == "cmsalarm")
|
|
{
|
|
// Get lang from threeletter
|
|
var lang = GetCultureFromThreeLetter(splittedFileName[1]);
|
|
|
|
if (lang != null)
|
|
languages.Add(lang);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
#endif
|
|
|
|
var lang = GetCultureFromThreeLetter("eng");
|
|
if (lang != null)
|
|
languages.Add(lang);
|
|
lang = GetCultureFromThreeLetter("ita");
|
|
if (lang != null)
|
|
languages.Add(lang);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Compilazione dizionario allarmi x lingua
|
|
/// </summary>
|
|
/// <param name="language"></param>
|
|
/// <param name="messages"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_GetTranslatedPlcMessages(string language, ref Dictionary<int, string> messages)
|
|
{
|
|
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 = THERMO_DICT_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());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Compilazione dizionario traduzioni THermo
|
|
/// </summary>
|
|
/// <param name="language"></param>
|
|
/// <param name="messages"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_GetTranslatedThermoLabels(string language, ref Dictionary<string, string> messages)
|
|
{
|
|
string filePath;
|
|
Dictionary<string, string> dict01 = new Dictionary<string, string>();
|
|
Dictionary<string, string> dict02 = new Dictionary<string, string>();
|
|
try
|
|
{
|
|
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(language);
|
|
string langName = "";
|
|
if (cultureInfo.IsNeutralCulture)
|
|
langName = cultureInfo.EnglishName;
|
|
else
|
|
langName = cultureInfo.Parent.EnglishName;
|
|
|
|
// Setup the Path for enums
|
|
filePath = THERMO_DICT_PATH + @"Enums_" + langName + @".txt";
|
|
|
|
// Read From File...
|
|
dict01 = File.ReadAllLines(filePath, Encoding.Default)
|
|
.Select(line => line.Split(','))
|
|
.Where(line => line.Count() == 2)
|
|
.ToDictionary(line => line[0].Trim(), line => line[1].Trim());
|
|
|
|
// Setup the Path for labels
|
|
filePath = THERMO_DICT_PATH + @"Labels_" + langName + @".txt";
|
|
|
|
// Read From File...
|
|
dict02 = File.ReadAllLines(filePath, Encoding.Default)
|
|
.Select(line => line.Split(','))
|
|
.Where(line => line.Count() == 2)
|
|
.ToDictionary(line => line[0].Trim(), line => line[1].Trim());
|
|
|
|
// combine 2 dictionary...
|
|
messages = dict01.Union(dict02).ToDictionary(d => d.Key, d => d.Value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
return NO_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// <summary>
|
|
/// Get the Nc Active Alarms
|
|
/// </summary>
|
|
/// <param name="alarms"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RActiveAlarms(ref List<AlarmModel> alarms)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the Date-Time of the NC
|
|
/// </summary>
|
|
/// <param name="ActualTime"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RDateTime(ref DateTime ActualTime)
|
|
{
|
|
ActualTime = DateTime.Now;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if the NC is in running state
|
|
/// </summary>
|
|
/// <param name="running"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RIsRunning(ref bool running)
|
|
{
|
|
ushort nProcess = 0;
|
|
// Get the number of processes
|
|
CmsError libraryError = NC_RProcessesNum(ref nProcess);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ushort i = 1;
|
|
running = false;
|
|
do
|
|
{
|
|
PROC_STATUS procStatus = PROC_STATUS.IDLE;
|
|
|
|
// Read process status
|
|
libraryError = PROC_RStatus(i, ref procStatus);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (procStatus == PROC_STATUS.RUN)
|
|
running = true;
|
|
i++;
|
|
} while (!running || i <= nProcess);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the NC Language
|
|
/// </summary>
|
|
/// <param name="Language"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RLanguage(ref CultureInfo Language)
|
|
{
|
|
// Read static data
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
Language = ConvertToSTEPLanguage(S7Language);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get CMS Machine number
|
|
/// </summary>
|
|
/// <param name="hasLetters"></param>
|
|
/// <param name="MachNumber"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RMachineNumber(bool hasLetters, ref string MachNumber)
|
|
{
|
|
if (!hasLetters)
|
|
{
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
MachNumber = Cms_MachNumber;
|
|
}
|
|
else
|
|
{
|
|
// New method to read machine number
|
|
List<byte> lists = new List<byte>();
|
|
CmsError libraryError = MEM_RWByteList(R, 0, NEW_MATR_MACC.MemType, NEW_MATR_MACC.Address, NEW_MATR_MACC.SubAddress, 0, 4, ref lists);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
lists.Reverse();
|
|
|
|
MachNumber = Encoding.ASCII.GetString(lists.ToArray().Reverse().ToArray());
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the NC model Name
|
|
/// </summary>
|
|
/// <param name="ModelName"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RModelName(ref string ModelName)
|
|
{
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ModelName = Cnc_name;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_RParam(short Index, short Bit, ref bool Value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
public override CmsError NC_RParam(short Index, ref byte Value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_RParam(short Index, ref short Value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_RParam(short Index, ref int Value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_RParam(short Index, ref double Value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the processes-count configurated
|
|
/// </summary>
|
|
/// <param name="ProcNumber"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RProcessesNum(ref ushort ProcNumber)
|
|
{
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ProcNumber = (ushort)ConfChannelNo;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the NC Serial number
|
|
/// </summary>
|
|
/// <param name="serialNumber"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RSerialNumber(ref string serialNumber)
|
|
{
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
serialNumber = Cnc_SeriesNum;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the NC Software Version
|
|
/// </summary>
|
|
/// <param name="SWV"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RSoftwareVersion(ref string SWV)
|
|
{
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
SWV = Cnc_SftVersion;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get NC unit of measure
|
|
/// </summary>
|
|
/// <param name="unitOfMeasure"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_RUnitOfMeasure(ref string unitOfMeasure)
|
|
{
|
|
CmsError libraryError = ReadStaticNCData();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
unitOfMeasure = UnitOfMeasure;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the Nc Active Page of the NC
|
|
/// </summary>
|
|
/// <param name="screen"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_SetScreenVisible(SCREEN_PAGE screen)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the NC Language
|
|
/// </summary>
|
|
/// <param name="Language"></param>
|
|
/// <returns></returns>
|
|
public override CmsError NC_WLanguage(CultureInfo Language)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError NC_WMDICommand(int processId, string mdiString)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
public override CmsError PLC_RActiveClient(ref int clientId)
|
|
{
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
byte readValues = 0;
|
|
libraryError = MEM_RWByte(R, true, 0, ACTIVE_CLIENT.MemType, ACTIVE_CLIENT.Address, ACTIVE_CLIENT.SubAddress, 0, ref readValues);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Convert integer array into bit array
|
|
bool[] statusBits = ByteToBits(readValues);
|
|
// check which bit is set
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if (statusBits[i])
|
|
clientId = i + 1;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Active message list
|
|
/// </summary>
|
|
/// <param name="alarms"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RActiveMessages(ref List<PlcAlarmModel> alarms)
|
|
{
|
|
// FIXME TODO controllare
|
|
bool[] statusBits;
|
|
int i = 0;
|
|
List<int> readValues = new List<int>();
|
|
List<byte> currMem = new List<byte>();
|
|
CmsError libraryError;
|
|
try
|
|
{
|
|
alarms.Clear();
|
|
|
|
// Read on data from memory
|
|
libraryError = MEM_RWIntegerList(R, 0,
|
|
ALARMS_STATUS.MemType,
|
|
ALARMS_STATUS.Address,
|
|
ALARMS_STATUS.SubAddress,
|
|
(ALARMS_STATUS.Size / 4) + (ALARMS_DATA.Size / 2), // status_bytes / 4 + data_word / 2
|
|
ref readValues);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// leggo a BYTE
|
|
libraryError = MEM_RWByteList(R, 0,
|
|
ALARMS_STATUS.MemType,
|
|
ALARMS_STATUS.Address,
|
|
ALARMS_STATUS.SubAddress,
|
|
0,
|
|
(ALARMS_STATUS.Size), // status_bytes
|
|
ref currMem);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
alarms.Clear();
|
|
|
|
// Convert integer array into bit array
|
|
statusBits = IntToBits(readValues.ToArray());
|
|
|
|
BitArray bArray = new BitArray(currMem.ToArray());
|
|
|
|
for (i = 0; i < ALARMS_STATUS.Size * 8; i++)
|
|
{
|
|
// If alarm is active
|
|
if (bArray[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_RAssistedToolingData(ref AssistedToolingModel data)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Production Info data
|
|
/// </summary>
|
|
/// <param name="currProdInfo"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RAxesMov(ref ThermoModels.AxisRT currProdInfo)
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
#if false
|
|
// converto!
|
|
currProdInfo = new ThermoModels.ProdInfoModel()
|
|
{
|
|
NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()),
|
|
NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()),
|
|
// cicli preriscaldo? FIXME TODO
|
|
TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()),
|
|
TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()),
|
|
TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()),
|
|
TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()),
|
|
TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()),
|
|
MaterialTempEndWarm = S7.Net.Types.Double.FromByteArray(currMem.Skip(26).Take(4).ToArray()),
|
|
MaterialTempEndVent = S7.Net.Types.Double.FromByteArray(currMem.Skip(30).Take(4).ToArray()),
|
|
MoldTemp = S7.Net.Types.Double.FromByteArray(currMem.Skip(34).Take(4).ToArray()),
|
|
VacuumReadVal = S7.Net.Types.Double.FromByteArray(currMem.Skip(38).Take(4).ToArray()),
|
|
MouldEnergyOUT = S7.Net.Types.Double.FromByteArray(currMem.Skip(42).Take(4).ToArray()),
|
|
MouldEnergyIN = S7.Net.Types.Double.FromByteArray(currMem.Skip(46).Take(4).ToArray())
|
|
};
|
|
#endif
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RAxesResetData(ref AxisResetDataModel axisResetData)
|
|
{
|
|
byte value = 0;
|
|
// Read byte from memory
|
|
CmsError libraryError = MEM_RWByte(R, true, 0, AXIS_RESET_PROCEDURE.MemType, AXIS_RESET_PROCEDURE.Address, AXIS_RESET_PROCEDURE.SubAddress, 0, ref value);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Check last bit if is active
|
|
if ((value & 128) == 128)
|
|
{
|
|
// Set to 0 last bit( isActive bit x - 128 )
|
|
// From 0 to 6 bit represents percentage
|
|
// If higher than 100 then value = 100
|
|
byte percentage = value - 128 > 100 ? (byte)100 : (byte)(value - 128);
|
|
axisResetData = new AxisResetDataModel()
|
|
{
|
|
IsActive = true,
|
|
Percentage = percentage
|
|
};
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Axis Info data
|
|
/// </summary>
|
|
/// <param name="currParamList"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RAxisInfoList(ref Dictionary<int, ThermoModels.AxisInfo> currAxisInfo)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 8;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
libraryError = MEM_RWByteList(R, 0, AXES_INFO.MemType, AXES_INFO.Address, AXES_INFO.SubAddress, 0, AXES_INFO.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < AXES_INFO.Size / packSize; i++)
|
|
{
|
|
ThermoModels.AxisInfo currData = new ThermoModels.AxisInfo(i + 1, memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// solo se ID > 0...
|
|
if (currData.Id > 0)
|
|
{
|
|
// update oggetto thermoParamList...
|
|
if (currAxisInfo.ContainsKey(currData.Id))
|
|
{
|
|
try
|
|
{
|
|
currAxisInfo[currData.Id].ErrorCode = currData.ErrorCode;
|
|
currAxisInfo[currData.Id].MovPhase = currData.MovPhase;
|
|
currAxisInfo[currData.Id].StatusWord = currData.StatusWord;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
currAxisInfo.Add(currData.Id, currData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return libraryError;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Get current LOG Cycle data
|
|
/// </summary>
|
|
/// <param name="currParamList"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RLogCycleData(out List<ThermoModels.LogCycleData> currLogCycle)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 10;
|
|
currLogCycle = new List<ThermoModels.LogCycleData>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
libraryError = MEM_RWByteList(R, 0, LOG_CYCLE_DATA.MemType, LOG_CYCLE_DATA.Address, LOG_CYCLE_DATA.SubAddress, 0, LOG_CYCLE_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < LOG_CYCLE_DATA.Size / packSize; i++)
|
|
{
|
|
ThermoModels.LogCycleData currData = new ThermoModels.LogCycleData(memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// se il valore ricevuto di evento è > 0...
|
|
if (currData.Code > 0)
|
|
{
|
|
try
|
|
{
|
|
currLogCycle.Add(currData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Axis RT data
|
|
/// </summary>
|
|
/// <param name="currParamList"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RAxisRTList(ref Dictionary<int, ThermoModels.AxisRT> currAxisRT)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<byte> currMem = new List<byte>();
|
|
int packSize = 12;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
libraryError = MEM_RWByteList(R, 0, AXES_RTDATA.MemType, AXES_RTDATA.Address, AXES_RTDATA.SubAddress, 0, AXES_RTDATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto a blocchi di byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
for (int i = 0; i < AXES_RTDATA.Size / packSize; i++)
|
|
{
|
|
ThermoModels.AxisRT currData = new ThermoModels.AxisRT(i + 1, memArray.Skip(i * packSize).Take(packSize).ToArray());
|
|
// solo se ID > 0...
|
|
if (currData.Id > 0)
|
|
{
|
|
// update oggetto thermoParamList...
|
|
if (currAxisRT.ContainsKey(currData.Id))
|
|
{
|
|
try
|
|
{
|
|
currAxisRT[currData.Id].Position = currData.Position;
|
|
currAxisRT[currData.Id].Speed = currData.Speed;
|
|
currAxisRT[currData.Id].Load = currData.Load;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
currAxisRT.Add(currData.Id, currData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return libraryError;
|
|
}
|
|
|
|
public override CmsError PLC_RCandy(ref long value)
|
|
{
|
|
// Long is formed by a integer + word
|
|
// Read word
|
|
ushort word = 0;
|
|
CmsError libraryError = MEM_RWWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Read first int
|
|
uint firtInt = 0;
|
|
libraryError = MEM_RWDWord(R, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref firtInt);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Build Long value
|
|
value = ((long)firtInt << 16) + word;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RExpiredCandy(ref bool value)
|
|
{
|
|
CmsError libraryError = MEM_RWBoolean(R, true, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RFunctionAccess(ref List<FunctionalityModel> functions)
|
|
{
|
|
List<int> readValues = new List<int>();
|
|
int numberOfIntegers = FUNCTION_ACCESS.Size / 4;
|
|
// Read functions access data from memory
|
|
CmsError libraryError = MEM_RWIntegerList(R, 0, FUNCTION_ACCESS.MemType, FUNCTION_ACCESS.Address, FUNCTION_ACCESS.SubAddress, numberOfIntegers, ref readValues);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
functions = new List<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,
|
|
// forzo a true perché non gestita dal PLC
|
|
IsActive = true //bits[i]
|
|
});
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get gauge data
|
|
/// </summary>
|
|
/// <param name="gaugeData"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RGaugeData(ref ThermoModels.LiveProdDataModel gaugeData)
|
|
{
|
|
List<int> Values = new List<int>();
|
|
CmsError libraryError = MEM_RWIntegerList(R, 1, MACHINE_GAUGE_DATA.MemType, MACHINE_GAUGE_DATA.Address, MACHINE_GAUGE_DATA.SubAddress, MACHINE_GAUGE_DATA.Size / 4, ref Values);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
gaugeData = new ThermoModels.LiveProdDataModel()
|
|
{
|
|
TimeAdv = Convert.ToUInt32(Values[0]),
|
|
Power = Values[1],
|
|
Vacuum = Values[2],
|
|
Air = Values[3],
|
|
};
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RHeadsData(List<HeadDataModel> heads, int number)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read PLC current IO Channels visibility (conf)
|
|
/// </summary>
|
|
/// <param name="currThermoIOVis">Visibility status for all channels</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RIOChannelsConf(ref ThermoModels.ChanIOVis currThermoIOVis)
|
|
{
|
|
CmsError currError = NO_ERROR;
|
|
// refresh dati
|
|
refreshChIOVisib();
|
|
|
|
// copio liste in output...
|
|
currThermoIOVis = ThermoIOVis;
|
|
|
|
// esco
|
|
return currError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read PLC current IO Channels VALUES (actual + forced)
|
|
/// </summary>
|
|
/// <param name="currThermoIOVal">Values for channels</param>
|
|
/// <param name="currThermoIOFor">Indicates if values are forced by UI</param>
|
|
/// <param name="currThermoIOValFor">Values forced by UI</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RIOChannelsVal(ref ThermoModels.ChanIOVal currThermoIOVal, ref ThermoModels.ChanIOFor currThermoIOFor, ref ThermoModels.ChanIOValFor currThermoIOValFor)
|
|
{
|
|
CmsError currError = NO_ERROR;
|
|
// refresh dati veloci (valori)
|
|
refreshChIOVal();
|
|
refreshChIOForced();
|
|
refreshChIOForcedVal();
|
|
|
|
// copio liste in output...
|
|
currThermoIOVal = ThermoIOVal;
|
|
currThermoIOFor = ThermoIOFor;
|
|
currThermoIOValFor = ThermoIOValFor;
|
|
|
|
// esco
|
|
return currError;
|
|
}
|
|
|
|
public override CmsError PLC_RM154Data(ref List<M154DataModel> data, ref bool MTCOnOff)
|
|
{
|
|
// FIXME TODO - levare? inserito anche endiannes
|
|
|
|
MTCOnOff = false;
|
|
CmsError libraryError = MEM_RWBoolean(R, true, 0, M154_SWITCH_ONOFF.MemType, M154_SWITCH_ONOFF.Address, M154_SWITCH_ONOFF.SubAddress, 1, ref MTCOnOff);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
byte val = 0;
|
|
libraryError = MEM_RWByte(R, true, 0, M154_STROBE.MemType, M154_STROBE.Address, M154_STROBE.SubAddress, 0, ref val);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Convert a byte to an array of booleans
|
|
bool[] bits = ByteToBits(val);
|
|
string[] parameters;
|
|
string tmpStr = "";
|
|
|
|
for (uint processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
|
|
{
|
|
if (bits[processId - 1])
|
|
{
|
|
// Read active program line
|
|
libraryError = PROC_ReadActiveLine(processId, ref tmpStr);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Parse parameters
|
|
parameters = ExtractM154ParametersFromNcCodeLine(tmpStr);
|
|
data.Add(new M154DataModel()
|
|
{
|
|
Process = processId,
|
|
IsNeeded = bits[processId - 1],
|
|
Parameters = parameters
|
|
});
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RM156Data(ref List<M156InputIsNeededModel> value)
|
|
{
|
|
// NB: da verificare se sia corretto o meno come BIT ARRAY...
|
|
|
|
byte val = 0;
|
|
List<byte> vals = new List<byte>();
|
|
CmsError libraryError = MEM_RWByte(R, false, 0, M156_INPUT_NEEDED.MemType, M156_INPUT_NEEDED.Address, M156_INPUT_NEEDED.SubAddress, 0, ref val);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
libraryError = MEM_RWByteList(R, 0, M156_INPUT_ID_LIST.MemType, M156_INPUT_ID_LIST.Address, M156_INPUT_ID_LIST.SubAddress, 0, M156_INPUT_ID_LIST.Size, ref vals);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
bool[] bits = ByteToBits(val);
|
|
|
|
// FORZO: 1 solo processo
|
|
//for (int processId = 1; processId <= MAX_PROCESS_NUMBER; processId++)
|
|
for (int processId = 1; processId <= 1; processId++)
|
|
{
|
|
if (bits[processId - 1])
|
|
{
|
|
// leggo x compatibilità la risposta standard
|
|
double responseVal = 0;
|
|
// Read machine variable
|
|
libraryError = MEM_RWDouble(R, 0, M156_RESPONSE_MEMORY.MemType, M156_RESPONSE_MEMORY.Address, M156_RESPONSE_MEMORY.SubAddress + (int)processId - 1, ref responseVal);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// Parse line & get parameters
|
|
value.Add(new M156InputIsNeededModel()
|
|
{
|
|
Process = (uint)processId,
|
|
Id = vals.ElementAt(processId - 1),
|
|
Value = responseVal
|
|
});
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// MACHINE COUNTERS
|
|
public override CmsError PLC_RMachineCounters(ref List<CounterModel> counters)
|
|
{
|
|
List<uint> val = new List<uint>();
|
|
// Read ints
|
|
CmsError libraryError = MEM_RWDWordList(R, 0, COUNTERS_DATA.MemType, COUNTERS_DATA.Address, COUNTERS_DATA.SubAddress, COUNTERS_DATA.Size / 4, ref val);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Set return value
|
|
uint i = 0;
|
|
counters = val.Select(x => new CounterModel()
|
|
{
|
|
Id = i++,
|
|
Value = x
|
|
})
|
|
.ToList();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Modules Block list
|
|
/// </summary>
|
|
/// <param name="onlyRT">updates only RT parameters (false = update all)</param>
|
|
/// <param name="currModulesBlockList"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RModulesBlockList(bool onlyRT, ref Dictionary<int, ThermoModels.ModuleBlock> currModulesBlockList)
|
|
{
|
|
// se richiesto NON SOLO RT faccio refresh anche dati "lenti"
|
|
if (!onlyRT)
|
|
{
|
|
refreshMemModBlockParameter();
|
|
}
|
|
// refresh dati veloci / RT
|
|
refreshMemModBlockParameterRT();
|
|
|
|
// copio lista act in output...
|
|
currModulesBlockList = ThermoModuleList;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_ROperatorInputIsNeeded(ref List<M155InputIsNeededModel> value)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RPowerOnData(ref PreAndPostPowerOnModel powerOnModel)
|
|
{
|
|
//int readValue = 0;
|
|
//// Read pre power on and post power on data from memory
|
|
//CmsError libraryError = MEM_RWInteger(R, 0, PRE_POST_POWER_ON.MemType, PRE_POST_POWER_ON.Address, PRE_POST_POWER_ON.SubAddress, ref readValue);
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
List<byte> currMem = new List<byte>();
|
|
libraryError = MEM_RWByteList(R, 0, PRE_POST_POWER_ON.MemType, PRE_POST_POWER_ON.Address, PRE_POST_POWER_ON.SubAddress, 0, 4, ref currMem);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
bool[] bits = new bool[32];
|
|
|
|
// Convert int into to true/false array
|
|
//bits = IntToBits(readValue);
|
|
var bArray = new BitArray(currMem.ToArray());
|
|
bArray.CopyTo(bits, 0);
|
|
|
|
// 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] },
|
|
BarriersNotOk = new PowerOnDataModel() { Id = 7, Active = bits[6], Clickable = bits[22] }
|
|
};
|
|
|
|
// 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Production Cycle data
|
|
/// </summary>
|
|
/// <param name="currProdCycle"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RProdCycle(ref ThermoModels.ProdCycleModel currProdCycle)
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_CYCLE.MemType, PROCESS_PROD_CYCLE.Address, PROCESS_PROD_CYCLE.SubAddress, 0, PROCESS_PROD_CYCLE.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// converto!
|
|
currProdCycle = new ThermoModels.ProdCycleModel()
|
|
{
|
|
Status = S7.Net.Types.Word.FromByteArray(currMem.Skip(0).Take(2).ToArray()),
|
|
MessageId = S7.Net.Types.Word.FromByteArray(currMem.Skip(2).Take(2).ToArray()),
|
|
Mode = S7.Net.Types.Byte.FromByteArray(currMem.Skip(4).Take(1).ToArray()),
|
|
Submode = S7.Net.Types.Byte.FromByteArray(currMem.Skip(5).Take(1).ToArray()),
|
|
TimeAdv = S7.Net.Types.DWord.FromByteArray(currMem.Skip(6).Take(4).ToArray())
|
|
};
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Production Info data
|
|
/// </summary>
|
|
/// <param name="currProdInfo"></param>
|
|
/// <returns></returns>
|
|
///
|
|
public override CmsError PLC_RProdInfo(ref ThermoModels.ProdInfoModel currProdInfo)
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// converto!
|
|
currProdInfo = new ThermoModels.ProdInfoModel()
|
|
{
|
|
NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()),
|
|
NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()),
|
|
TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()),
|
|
TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()),
|
|
TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()),
|
|
TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()),
|
|
TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()),
|
|
MaterialTempEndWarm = S7.Net.Types.Real.FromByteArray(currMem.Skip(26).Take(4).ToArray()),
|
|
MaterialTempEndVent = S7.Net.Types.Real.FromByteArray(currMem.Skip(30).Take(4).ToArray()),
|
|
MoldTemp = S7.Net.Types.Real.FromByteArray(currMem.Skip(34).Take(4).ToArray()),
|
|
VacuumReadVal = S7.Net.Types.Real.FromByteArray(currMem.Skip(38).Take(4).ToArray()),
|
|
MouldEnergyOUT = S7.Net.Types.Real.FromByteArray(currMem.Skip(42).Take(4).ToArray()),
|
|
MouldEnergyIN = S7.Net.Types.Real.FromByteArray(currMem.Skip(46).Take(4).ToArray()),
|
|
NumPreHot = S7.Net.Types.Int.FromByteArray(currMem.Skip(50).Take(2).ToArray())
|
|
};
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// read current recipe parameter list
|
|
/// </summary>
|
|
/// <param name="onlyRT">updates only RT parameters (false = update all)</param>
|
|
/// <param name="currParamList"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RRecipeParamList(bool onlyRT, ref Dictionary<int, ThermoModels.RecipeParam> currParamList)
|
|
{
|
|
CmsError currError = NO_ERROR;
|
|
// 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 currError;
|
|
}
|
|
|
|
public override CmsError PLC_RScadaSiemens(ref List<ScadaObjectModel> objects)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
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 libraryError = 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;
|
|
libraryError = 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;
|
|
libraryError = 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;
|
|
libraryError = MEM_RWDouble(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
|
|
value = val;
|
|
}
|
|
else
|
|
{
|
|
// FIXME TODO verificare endianness (qui true)
|
|
// read BYTE
|
|
byte val = 0;
|
|
libraryError = MEM_RWByte(R, true, 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)
|
|
{
|
|
// FIXME TODO verificare endianness, qui false
|
|
// read BOOL
|
|
bool val = false;
|
|
libraryError = MEM_RWBoolean(R, false, 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 libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read Status/command words
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RStatusCommand(ref List<ushort> statusCmd)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
// leggo intera area DWORD e di conseguenza processo...
|
|
statusCmd = new List<ushort>();
|
|
libraryError = MEM_RWWordList(R, 0, STATUS_CMD_DATA.MemType, STATUS_CMD_DATA.Address, STATUS_CMD_DATA.SubAddress, STATUS_CMD_DATA.Size, ref statusCmd);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
public override CmsError PLC_RToolMovement(ref MovementBetweenMagazinesModel toolMovement)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RUserSoftKeys(ref List<SoftKeysModel> softKeys)
|
|
{
|
|
CmsError libraryError = PLC_RSoftKeys(USER_SOFTKEYS_VALUE, USER_SOFTKEYS_CLICKABLE, ref softKeys);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Warmers Channels list
|
|
/// </summary>
|
|
/// <param name="useCache">updates only READ parameters (false = update all data)</param>
|
|
/// <param name="currWarmerChannelList"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RWarmerChannelList(bool useCache, ref Dictionary<int, ThermoModels.WarmerChannel> currWarmerChannelList)
|
|
{
|
|
// refresh stato canale ESP[i]
|
|
refreshRiscStatus();
|
|
// refresh % lavoro attuale OVp[i]
|
|
refreshRiscPerc();
|
|
// refresh corrente attuale Ich[i]
|
|
refreshRiscActCurr();
|
|
// refresh setpoint PLC % (era 514 --> 627)
|
|
refreshRiscSetpointPLC();
|
|
|
|
// refresh dati status/comando termocamera
|
|
refreshRiscTermoCamCommStatus();
|
|
|
|
// refresh setpoint HMI canale % | Write
|
|
refreshRiscSetpointHMI();
|
|
|
|
if (!useCache)
|
|
{
|
|
// refresh abilitazione canale x thermoCam | Write
|
|
refreshRiscTermoCamEnab();
|
|
// refresh ultima temp canale letta da thermoCam | Write
|
|
refreshRiscTermoCamTempAct();
|
|
// refresh temp canale impostata x thermoCam | Write
|
|
refreshRiscTermoCamTempSet();
|
|
}
|
|
|
|
// copio lista act in output
|
|
currWarmerChannelList = ThermoWarmChannels;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Warmers VUMin data
|
|
/// </summary>
|
|
/// <param name="VUmin"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RWarmerConfVUMin(ref ushort VUmin)
|
|
{
|
|
// leggo da 513.0 --> default 210
|
|
VUmin = 230;
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// read actual data on memory...
|
|
CmsError libraryError = MEM_RWWord(R, 0, RISC_VU_MIN.MemType, RISC_VU_MIN.Address, RISC_VU_MIN.SubAddress, ref VUmin);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current Warmers ThermoCam Data
|
|
/// </summary>
|
|
/// <param name="currTCamData"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RWarmerTCamData(out ThermoModels.ThermoCam currTCamData)
|
|
{
|
|
// init...
|
|
bool currValue = false;
|
|
currTCamData = new ThermoModels.ThermoCam();
|
|
|
|
// leggo da PLC singoli bit...
|
|
CmsError libraryError = MEM_RWBoolean(R, true, 0, TCAM_STATW_DATA.MemType, TCAM_STATW_DATA.Address, TCAM_STATW_DATA.SubAddress, 0, ref currValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoCamData.ThermoOptionActive = currValue;
|
|
|
|
libraryError = MEM_RWBoolean(R, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 0, ref currValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoCamData.ThermoCamMode = currValue;
|
|
|
|
libraryError = MEM_RWBoolean(R, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 1, ref currValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
ThermoCamData.ThermoCamOnOff = currValue;
|
|
|
|
// restituisce status dei parametri termocamera (in cache...)
|
|
currTCamData = ThermoCamData;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
public override CmsError PLC_RWManageWatchdog()
|
|
{
|
|
// watchdog in memoria WORD --> true x endianness!
|
|
bool plcWatchdog = false;
|
|
CmsError libraryError = MEM_RWBoolean(R, true, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (plcWatchdog)
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
// tira su il bit...
|
|
plcWatchdog = true;
|
|
return MEM_RWBoolean(W, true, 0, NC_WATCHDOG.MemType, NC_WATCHDOG.Address, NC_WATCHDOG.SubAddress, 0, ref plcWatchdog);
|
|
}
|
|
|
|
public override CmsError PLC_RWorkedTimeHead(int head, ref uint time)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_RWorkedTimeMachine(ref uint time)
|
|
{
|
|
// Read Worked time
|
|
CmsError libraryError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write MULTIPLE Digital Out FORCED Status (bitmap)
|
|
/// </summary>
|
|
/// <param name="newValues">Oggetto valori da aggiornare (from HMI)</param>
|
|
/// <param name="nMaxParamWrite">num max parametri da scrivere singolarmente</param>
|
|
/// <param name="delayParamWrite">delay in scriottura multi parametri singoli</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_W_IO_AO_Reset(Dictionary<int, bool> newValues)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
List<ushort> rwValuesAO = new List<ushort>();
|
|
|
|
// leggo da PLC a array di byte di appoggio x visibilità AO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref rwValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
int bank = 0;
|
|
int pos = 0;
|
|
int size = 16;
|
|
// imposto i valori NUOVI... cerco il BANK da 16 bit...
|
|
foreach (var item in newValues)
|
|
{
|
|
bank = item.Key / size;
|
|
pos = item.Key % size;
|
|
// aggiorno
|
|
if (item.Value)
|
|
{
|
|
rwValuesAO[bank] = (ushort)(((int)rwValuesAO[bank]).SetBitOne(pos));
|
|
}
|
|
else
|
|
{
|
|
rwValuesAO[bank] = (ushort)(((int)rwValuesAO[bank]).SetBitZero(pos));
|
|
}
|
|
}
|
|
|
|
// scrivo!
|
|
libraryError = MEM_RWWordList(W, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref rwValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write MULTIPLE Analog Out values (+ force)
|
|
/// </summary>
|
|
/// <param name="newValues">Oggetto valori da aggiornare (from HMI)</param>
|
|
/// <param name="nMaxParamWrite">num max parametri da scrivere singolarmente</param>
|
|
/// <param name="delayParamWrite">delay in scriottura multi parametri singoli</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_W_IO_AO_Val(Dictionary<int, int> newValues)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<short> rwValuesAO = new List<short>();
|
|
Dictionary<int, bool> newForced = new Dictionary<int, bool>();
|
|
|
|
// leggo da PLC valori AO...
|
|
libraryError = MEM_RWShortList(R, 0, IO_AO_VAL_FOR.MemType, IO_AO_VAL_FOR.Address, IO_AO_VAL_FOR.SubAddress, IO_AO_VAL_FOR.Size, ref rwValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// aggiorno valori ricevuti// imposto i valori NUOVI... cerco il BANK da 16 bit...
|
|
foreach (var item in newValues)
|
|
{
|
|
rwValuesAO[item.Key] = (short)item.Value;
|
|
newForced.Add(item.Key, true);
|
|
}
|
|
|
|
// scrivo valori
|
|
libraryError = MEM_RWShortList(W, 0, IO_AO_VAL_FOR.MemType, IO_AO_VAL_FOR.Address, IO_AO_VAL_FOR.SubAddress, IO_AO_VAL_FOR.Size, ref rwValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// scrivo forced
|
|
PLC_W_IO_AO_Reset(newForced);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write MULTIPLE Digital Out FORCED Status (bitmap)
|
|
/// </summary>
|
|
/// <param name="newValues">Oggetto valori da aggiornare (from HMI)</param>
|
|
/// <param name="nMaxParamWrite">num max parametri da scrivere singolarmente</param>
|
|
/// <param name="delayParamWrite">delay in scriottura multi parametri singoli</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_W_IO_DO_Reset(Dictionary<int, bool> newValues)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
List<ushort> rwValuesDO = new List<ushort>();
|
|
|
|
// leggo da PLC a array di byte di appoggio x visibilità DO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref rwValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
int bank = 0;
|
|
int pos = 0;
|
|
int size = 16;
|
|
// imposto i valori NUOVI... cerco il BANK da 16 bit...
|
|
foreach (var item in newValues)
|
|
{
|
|
bank = item.Key / size;
|
|
pos = item.Key % size;
|
|
// aggiorno
|
|
if (item.Value)
|
|
{
|
|
rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitOne(pos));
|
|
}
|
|
else
|
|
{
|
|
rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitZero(pos));
|
|
}
|
|
}
|
|
|
|
// scrivo!
|
|
libraryError = MEM_RWWordList(W, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref rwValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write MULTIPLE Digital Out values (+ force)
|
|
/// </summary>
|
|
/// <param name="newValues">Oggetto valori da aggiornare (from HMI)</param>
|
|
/// <param name="nMaxParamWrite">num max parametri da scrivere singolarmente</param>
|
|
/// <param name="delayParamWrite">delay in scriottura multi parametri singoli</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_W_IO_DO_Val(Dictionary<int, bool> newValues)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
List<ushort> rwValuesDO = new List<ushort>();
|
|
Dictionary<int, bool> newForced = new Dictionary<int, bool>();
|
|
|
|
// leggo da PLC valori DO...
|
|
libraryError = MEM_RWWordList(R, 0, IO_DO_VAL_FOR.MemType, IO_DO_VAL_FOR.Address, IO_DO_VAL_FOR.SubAddress, IO_DO_VAL_FOR.Size, ref rwValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
int bank = 0;
|
|
int pos = 0;
|
|
int size = 16;
|
|
// imposto i valori NUOVI... cerco il BANK da 16 bit...
|
|
foreach (var item in newValues)
|
|
{
|
|
bank = item.Key / size;
|
|
pos = item.Key % size;
|
|
// aggiorno
|
|
if (item.Value)
|
|
{
|
|
rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitOne(pos));
|
|
}
|
|
else
|
|
{
|
|
rwValuesDO[bank] = (ushort)(((int)rwValuesDO[bank]).SetBitZero(pos));
|
|
}
|
|
newForced.Add(item.Key, true);
|
|
}
|
|
|
|
// scrivo!
|
|
libraryError = MEM_RWWordList(W, 0, IO_DO_VAL_FOR.MemType, IO_DO_VAL_FOR.Address, IO_DO_VAL_FOR.SubAddress, IO_DO_VAL_FOR.Size, ref rwValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// scrivo forced
|
|
PLC_W_IO_DO_Reset(newForced);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset ALL DO / AO forced bitmap
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_W_IO_ResetAll()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
List<ushort> writeValuesDO = new List<ushort>();
|
|
List<ushort> writeValuesAO = new List<ushort>();
|
|
// imposto a zero...
|
|
for (int i = 0; i < IO_DO_FORCE.Size; i++)
|
|
{
|
|
writeValuesDO.Add(0);
|
|
}
|
|
for (int i = 0; i < IO_AO_FORCE.Size; i++)
|
|
{
|
|
writeValuesAO.Add(0);
|
|
}
|
|
|
|
// scrivo su PLC
|
|
libraryError = MEM_RWWordList(W, 0, IO_DO_FORCE.MemType, IO_DO_FORCE.Address, IO_DO_FORCE.SubAddress, IO_DO_FORCE.Size, ref writeValuesDO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// scrivo su PLC
|
|
libraryError = MEM_RWWordList(W, 0, IO_AO_FORCE.MemType, IO_AO_FORCE.Address, IO_AO_FORCE.SubAddress, IO_AO_FORCE.Size, ref writeValuesAO);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
public override CmsError PLC_W154ManageAck(int processId)
|
|
{
|
|
return PLC_ManageActiveAck(M154_STROBE.Address, M154_STROBE.SubAddress, processId - 1, M154_ACK.Address, M154_ACK.SubAddress, processId - 1, M154_STROBE.MemType, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process conf request
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckConfRecipeRequest()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for config request RECIPE
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 9);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/// <summary>
|
|
/// Process conf request for RISK data
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckConfRiskRequest()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for config request RISK
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 8);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process conf request for FLIR picture request
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckFlirRequest()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for config request RISK
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 13);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process production info update
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckProdUpdate()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for prod update
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 4);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process end prod ack
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckPzProdEnd()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for prod update
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 12);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process start prod ack
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckPzProdStart()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for prod update
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 11);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process setpointHMI invalidated with ack
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAckSetpointInvalidated()
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// Call ack for prod update
|
|
libraryError = PLC_WAck(true, REQ_CONF_ACK, REQ_CONF_STROBE, 15);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
public override CmsError PLC_WAssistedToolingCmd(ushort toolId, ushort familyId, ushort shankId, ushort magazineId, ushort positionId, ASSISTED_TOOLING_ACTION action)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WCandy(long value)
|
|
{
|
|
// Long is formed by a integer + word
|
|
// Write Word
|
|
ushort word = (ushort)((value & 0xFFFF));
|
|
CmsError libraryError = MEM_RWWord(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress, ref word);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
int integer = (int)((value & 0xFFFFFFFF0000) >> 16);
|
|
// Write Integer (+1 is used because osai uses word)
|
|
libraryError = MEM_RWInteger(W, 0, CANDY_MEM.MemType, CANDY_MEM.Address, CANDY_MEM.SubAddress + 2, ref integer);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Rieggo il dato
|
|
long newVal = 0;
|
|
libraryError = PLC_RCandy(ref newVal);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Se i 2 dati coincidono ritorno OK
|
|
if (value == newVal)
|
|
return NO_ERROR;
|
|
else
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WExpiredCandy(bool value)
|
|
{
|
|
bool newVal = false;
|
|
|
|
//Scrivo il dato
|
|
CmsError libraryError = MEM_RWBoolean(W, true, 0, EXP_CANDY_MEM.MemType, EXP_CANDY_MEM.Address, EXP_CANDY_MEM.SubAddress, 5, ref value);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
else
|
|
{
|
|
//Leggo il dato
|
|
libraryError = PLC_RExpiredCandy(ref newVal);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
//Se i 2 dati coincidono ritorno OK
|
|
if (value == newVal)
|
|
return NO_ERROR;
|
|
else
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
}
|
|
|
|
public override CmsError PLC_WHeadOverride(uint id, HEAD_OVERRIDE_SIGN sign)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set Keyboard softkey ID
|
|
/// </summary>
|
|
/// <param name="idKey1">Softkey ID of the first button</param>
|
|
/// <param name="idKey2">Softkey ID of the second button</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WKeyboardSoftkey(ushort idKey1, ushort idKey2)
|
|
{
|
|
List<ushort> currMem = new List<ushort>();
|
|
currMem.Add(idKey1);
|
|
currMem.Add(idKey2);
|
|
CmsError libraryError = MEM_RWWordList(W, 0, KEYBOARD_STAR_MEMORY.MemType, KEYBOARD_STAR_MEMORY.Address, KEYBOARD_STAR_MEMORY.SubAddress, KEYBOARD_STAR_MEMORY.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WM156Response(int process, double responseVal)
|
|
{
|
|
// forzo process a 1...
|
|
process = 1;
|
|
CmsError libraryError = MEM_RWDouble(W, 0, M156_RESPONSE_MEMORY.MemType, M156_RESPONSE_MEMORY.Address, M156_RESPONSE_MEMORY.SubAddress + (int)process - 1, ref responseVal);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// FIXME TODO verifica se endianness vada gestita o meno (qui FALSE)
|
|
return PLC_WStrobe(false, M156_INPUT_ACK, M156_INPUT_STROBE, (uint)process);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request for mode selection via strobe
|
|
/// </summary>
|
|
/// <param name="mode">1: MAN, 2: AUTO, 3: SETUP</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WModeSel(int mode)
|
|
{
|
|
// se update --> scrivo strobe comando update...
|
|
if (mode == 1)
|
|
{
|
|
// Call confirm update
|
|
CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 6);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
else
|
|
if (mode == 2)
|
|
{
|
|
// Call confirm update
|
|
CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 5);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
else
|
|
if (mode == 3)
|
|
{
|
|
// Call confirm update
|
|
CmsError libraryError = PLC_WStrobe(true, REQ_MODE_ACK, REQ_MODE_STROBE, 7);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WOperatorInputResponse(int process, double responseVal)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WPowerOnData(uint id, bool value)
|
|
{
|
|
// Check bit range
|
|
if (id > 16)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Call restore message
|
|
CmsError libraryError = PLC_WStrobe(false, PRE_POST_POWER_ON_ACK, PRE_POST_POWER_ON_CLICKED, id);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set ProdInfo data
|
|
/// </summary>
|
|
/// <param name="numTarget">Qty requested (target)</param>
|
|
/// <param name="doReset">Reset counter (actual counter)</param>
|
|
/// <param name="preWarmCycle">Number of pre-warm cycle requested</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WProdInfo(short numTarget, bool doReset, short preWarmCycle)
|
|
{
|
|
List<byte> currMem = new List<byte>();
|
|
CmsError libraryError = MEM_RWByteList(R, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// converto!
|
|
var currProdInfo = new ThermoModels.ProdInfoModel()
|
|
{
|
|
NumTarget = S7.Net.Types.Int.FromByteArray(currMem.Skip(0).Take(2).ToArray()),
|
|
NumDone = S7.Net.Types.Int.FromByteArray(currMem.Skip(2).Take(2).ToArray()),
|
|
PreWarmCycle = S7.Net.Types.Int.FromByteArray(currMem.Skip(4).Take(2).ToArray()),
|
|
TimeWarm = S7.Net.Types.DInt.FromByteArray(currMem.Skip(6).Take(4).ToArray()),
|
|
TimeVent = S7.Net.Types.DInt.FromByteArray(currMem.Skip(10).Take(4).ToArray()),
|
|
TimeVacuum = S7.Net.Types.DInt.FromByteArray(currMem.Skip(14).Take(4).ToArray()),
|
|
TimeCycleGross = S7.Net.Types.DInt.FromByteArray(currMem.Skip(18).Take(4).ToArray()),
|
|
TimeCycleNet = S7.Net.Types.DInt.FromByteArray(currMem.Skip(22).Take(4).ToArray()),
|
|
MaterialTempEndWarm = S7.Net.Types.Real.FromByteArray(currMem.Skip(26).Take(4).ToArray()),
|
|
MaterialTempEndVent = S7.Net.Types.Real.FromByteArray(currMem.Skip(30).Take(4).ToArray()),
|
|
MoldTemp = S7.Net.Types.Real.FromByteArray(currMem.Skip(34).Take(4).ToArray()),
|
|
VacuumReadVal = S7.Net.Types.Real.FromByteArray(currMem.Skip(38).Take(4).ToArray()),
|
|
MouldEnergyOUT = S7.Net.Types.Real.FromByteArray(currMem.Skip(42).Take(4).ToArray()),
|
|
MouldEnergyIN = S7.Net.Types.Real.FromByteArray(currMem.Skip(46).Take(4).ToArray()),
|
|
NumPreHot = S7.Net.Types.Int.FromByteArray(currMem.Skip(50).Take(2).ToArray())
|
|
};
|
|
|
|
// aggiorno...
|
|
currProdInfo.NumTarget = numTarget;
|
|
currProdInfo.PreWarmCycle = preWarmCycle;
|
|
// converto a byte...
|
|
List<byte> newMem = currProdInfo.convertToByte().ToList();
|
|
// riscrivo!!!!
|
|
libraryError = MEM_RWByteList(W, 0, PROCESS_PROD_INFO.MemType, PROCESS_PROD_INFO.Address, PROCESS_PROD_INFO.SubAddress, 0, PROCESS_PROD_INFO.Size, ref newMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (doReset)
|
|
{
|
|
// send strobe of NEW WorkOrder / reset QTY
|
|
libraryError = PLC_WStrobe(true, PROD_ACK, PROD_STROBE, 10);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm/Cancel recipe modifications
|
|
/// </summary>
|
|
/// <param name="confirmUpdate">true: HMI --> PLC, false: PLC --> HMI</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WRecipeEdit(bool confirmUpdate)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
// se update --> scrivo strobe comando update...
|
|
if (confirmUpdate)
|
|
{
|
|
// Call confirm update
|
|
libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 2);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
// altrimenti mando strobe comando cancel...
|
|
else
|
|
{
|
|
// Call cancel update
|
|
libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 3);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write recipe updated MULTIPLE parameter
|
|
/// </summary>
|
|
/// <param name="newParameters">Oggetto parametri da aggiornare (from HMI)</param>
|
|
/// <param name="nMaxParamWrite">num max parametri da scrivere singolarmente, default = 10</param>
|
|
/// <param name="delayParamWrite">delay in scriottura multi parametri singoli, default = 20ms</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WRecipeParameters(Dictionary<int, int> newParameters, int nMaxParamWrite = 10, int delayParamWrite = 20)
|
|
{
|
|
// init variabili accessorie
|
|
CmsError libraryError = NO_ERROR;
|
|
List<byte> currMem = new List<byte>();
|
|
int memIndex = 0;
|
|
int packSize = 20;
|
|
|
|
// 2020.09.03: ricevuto da chiamata, dovrebbe essere 5 parametri x scrivere tutto (era 30 prima di 2008.08.07)
|
|
bool writeSingle = newParameters.Count < nMaxParamWrite;
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
libraryError = MEM_RWByteList(R, 0, PARAMETER_DATA.MemType, PARAMETER_DATA.Address, PARAMETER_DATA.SubAddress, 0, PARAMETER_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
PlcParam currParam;
|
|
List<byte> newMem = new List<byte>();
|
|
// controllo SE ho dati...
|
|
if (currMem.Count > 0)
|
|
{
|
|
// converto in array di byte...
|
|
byte[] memArray = currMem.ToArray();
|
|
// ciclo x ogni parametro x aggiornare il valore...
|
|
foreach (var item in newParameters)
|
|
{
|
|
memIndex = (item.Key - 1) * packSize;
|
|
// recupero oggetto parametri
|
|
currParam = new PlcParam(memArray.Skip(memIndex).Take(packSize).ToArray());
|
|
if (currParam.Id > 0)
|
|
{
|
|
// se servisse resetto...
|
|
if (currParam.Id != (short)item.Key)
|
|
currParam.Id = (short)item.Key;
|
|
currParam.SetpointHMI = (int)item.Value;
|
|
// scrivo 1:1 se pochi dati SOLO i singoli valori HMI
|
|
if (writeSingle)
|
|
{
|
|
newMem = S7.Net.Types.DInt.ToByteArray(currParam.SetpointHMI).ToList();// currParam.convertToByte().ToList();
|
|
libraryError = MEM_RWByteList(W, 0, PARAMETER_DATA.MemType, PARAMETER_DATA.Address, PARAMETER_DATA.SubAddress + packSize * (currParam.Id - 1) + 2, 0, 4, ref newMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
// attendo x sicurezza...
|
|
Thread.Sleep(delayParamWrite);
|
|
}
|
|
else
|
|
{
|
|
// accodo su memoria generale
|
|
Buffer.BlockCopy(currParam.convertToByte(), 0, memArray, memIndex, packSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
// converto nuova memoria
|
|
newMem = memArray.ToList();
|
|
memIndex = 0;
|
|
if (!writeSingle)
|
|
{
|
|
// SCRIVO in blocco!
|
|
libraryError = MEM_RWByteList(W, 0, PARAMETER_DATA.MemType, PARAMETER_DATA.Address, PARAMETER_DATA.SubAddress, 0, PARAMETER_DATA.Size, ref newMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send axis command
|
|
/// </summary>
|
|
/// <param name="AxisNum">ID asse</param>
|
|
/// <param name="CommandBit">Comando (0..15)</param>
|
|
/// <param name="WritePos">Indica se scrivere la TargetPos</param>
|
|
/// <param name="TargetPos">Posizione target</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAxisCommand(int AxisNum, uint CommandBit, bool WritePos, double TargetPos)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
if (WritePos)
|
|
{
|
|
MEMORY_CELL caTgtPos = new MEMORY_CELL(AXES_COMMAND.MemType, AXES_COMMAND.Address, AXES_COMMAND.SubAddress + ((AxisNum - 1) * 8) + 4, 2);
|
|
// in primis scrivo la TargetPos nei 4 byte DWord...
|
|
libraryError = MEM_RWDouble(W, 0, caTgtPos.MemType, caTgtPos.Address, caTgtPos.SubAddress, ref TargetPos);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
// ...è permesso solo 0..7
|
|
if (CommandBit >= 1 && CommandBit < 8)
|
|
{
|
|
// posizione: è da array assi 0..n-1, 8byte ogni asse
|
|
MEMORY_CELL currAxAck = new MEMORY_CELL(AXES_COMMAND.MemType, AXES_COMMAND.Address, AXES_COMMAND.SubAddress + ((AxisNum - 1) * 8), 2);
|
|
MEMORY_CELL currAxStr = new MEMORY_CELL(AXES_COMMAND.MemType, AXES_COMMAND.Address, AXES_COMMAND.SubAddress + ((AxisNum - 1) * 8 + 2), 2);
|
|
|
|
// Call confirm update
|
|
libraryError = PLC_WStrobe(true, currAxAck, currAxStr, CommandBit);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send Axes Gen Control
|
|
/// </summary>
|
|
/// <param name="AdvMode">Boolean for advanced mode</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WAxisGeneralControl(bool AdvMode)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// preparo la word
|
|
ushort controlData = 0;
|
|
if (AdvMode)
|
|
{
|
|
controlData = 1;
|
|
}
|
|
|
|
MEMORY_CELL caTgtPos = new MEMORY_CELL(AXES_GEN_CONTROL.MemType, AXES_GEN_CONTROL.Address, AXES_GEN_CONTROL.SubAddress, 2);
|
|
// in primis scrivo la TargetPos nei 4 byte DWord...
|
|
libraryError = MEM_RWWord(W, 0, caTgtPos.MemType, caTgtPos.Address, caTgtPos.SubAddress, ref controlData);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Read Axes Gen Control
|
|
/// </summary>
|
|
/// <param name="AdvMode">Boolean for advanced mode</param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_RAxisGeneralStatus(ref bool AdvMode)
|
|
{
|
|
CmsError libraryError = NO_ERROR;
|
|
|
|
// preparo la word
|
|
ushort controlData = 0;
|
|
|
|
MEMORY_CELL caTgtPos = new MEMORY_CELL(AXES_GEN_STATUS.MemType, AXES_GEN_STATUS.Address, AXES_GEN_STATUS.SubAddress, 2);
|
|
// in primis scrivo la TargetPos nei 4 byte DWord...
|
|
libraryError = MEM_RWWord(R, 0, caTgtPos.MemType, caTgtPos.Address, caTgtPos.SubAddress, ref controlData);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
AdvMode = (controlData == 1);
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
|
|
public override CmsError PLC_WRefreshAllMessages()
|
|
{
|
|
// imposto come UserSoftKey
|
|
return PLC_WUserSoftKey(REFRESH_ALL_ALARMS_SFKEY_INDEX);
|
|
}
|
|
|
|
public override CmsError PLC_WRefreshMessage(uint id)
|
|
{
|
|
// Check id range
|
|
if (id > ALARMS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Call restore message: is a BIT ARRAY --> false!
|
|
CmsError libraryError = PLC_WStrobe(false, ALARM_ACK, ALARM_REFRESH_STROBE, id);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WResetMachineCounters(uint counter)
|
|
{
|
|
// FIXME TODO verifica se endianness vada gestita o meno (qui FALSE)
|
|
bool isResettable = false;
|
|
CmsError libraryError = MEM_RWBoolean(R, false, 0, COUNTER_IS_RESETTABLE.MemType, COUNTER_IS_RESETTABLE.Address, COUNTER_IS_RESETTABLE.SubAddress, (int)(counter - 1), ref isResettable);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
if (!isResettable)
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
|
|
libraryError = PLC_WStrobe(false, COUNTER_IS_RESETTABLE_ACK, COUNTER_IS_RESETTABLE_STROBE, counter);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WResetWorkedTimeHead(int head)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WResetWorkedTimeMachine(uint time)
|
|
{
|
|
//FIXME TODO verificare endianness aree memoria
|
|
|
|
uint actTime = 0;
|
|
|
|
// Read actual Value
|
|
CmsError libraryError = MEM_RWDWord(R, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref actTime);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Per richiedere l'azzeramento del timer invio 4 volte il segnale velocemente al PLC
|
|
// Il PLC resetta il bit e aspetta quello successivo entro 500ms, se no abortisce
|
|
// Sfrutto così la velocità dei sw, cosa che un "nemico" a mano se provasse a forzare il bit non avrebbe
|
|
bool bitValue = true;
|
|
int nTry = 0;
|
|
|
|
for (int i = 0; i <= 4; i++)
|
|
{
|
|
//Scrivo il bit
|
|
bitValue = true;
|
|
nTry = 0;
|
|
libraryError = MEM_RWBoolean(W, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
//Aspetto che venga abbassato
|
|
do
|
|
{
|
|
Thread.Sleep(50);
|
|
nTry += 1;
|
|
libraryError = MEM_RWBoolean(R, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
} while (bitValue && nTry <= 10);
|
|
|
|
//se il valore è rimasto a 1 il plc non l'ha preso in carico, e abortisco
|
|
if (bitValue)
|
|
{
|
|
bitValue = true;
|
|
libraryError = MEM_RWBoolean(W, true, 0, MACHINE_RESET_WORKED_TIME.MemType, MACHINE_RESET_WORKED_TIME.Address, MACHINE_RESET_WORKED_TIME.SubAddress, 0, ref bitValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return PLC_NOT_RUNNING_ERROR;
|
|
}
|
|
else
|
|
{
|
|
//Se l'ha abbassato scrivo il nuovo dato
|
|
libraryError = MEM_RWDWord(W, 0, MACHINE_WORKED_TIME.MemType, MACHINE_WORKED_TIME.Address, MACHINE_WORKED_TIME.SubAddress, ref time);
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WRestoreMessage(uint id)
|
|
{
|
|
// Check id range
|
|
if (id > ALARMS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Call restore message: is a BIT ARRAY --> true!
|
|
CmsError libraryError = PLC_WStrobe(true, ALARM_ACK, ALARM_RESTORATION_STROBE, id);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WScadaValue(string memIndex, SCADA_MEM_TYPE memType, object value)
|
|
{
|
|
string[] index = memIndex.Split('.');
|
|
CmsError libraryError = NO_ERROR;
|
|
if (index.Count() == 0)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
else if (index.Count() == 2)
|
|
{
|
|
if (memType == SCADA_MEM_TYPE.INT)
|
|
{
|
|
// write INT
|
|
int val = Convert.ToInt32(value);
|
|
libraryError = MEM_RWInteger(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
}
|
|
else if (memType == SCADA_MEM_TYPE.WORD)
|
|
{ // write WORD
|
|
short val = Convert.ToInt16(value);
|
|
libraryError = MEM_RWShort(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
}
|
|
else if (memType == SCADA_MEM_TYPE.REAL)
|
|
{ // write DOUBLE
|
|
double val = Convert.ToDouble(value);
|
|
libraryError = MEM_RWDouble(W, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
|
}
|
|
else
|
|
{
|
|
// write byte
|
|
byte val = Convert.ToByte(value);
|
|
libraryError = MEM_RWByte(W, true, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), 0, ref val);
|
|
}
|
|
}
|
|
else if (index.Count() == 3 && memType == SCADA_MEM_TYPE.BOOL)
|
|
{
|
|
// write BOOL
|
|
bool val = Convert.ToBoolean(value);
|
|
libraryError = MEM_RWBoolean(W, false, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), Convert.ToInt32(index[2]), ref val);
|
|
}
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Confirm FLIR image acquired and copied to PLC (STR from server)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WStrFlirAcquired()
|
|
{
|
|
// Call confirm update
|
|
CmsError libraryError = PLC_WStrobe(true, PARAMETER_EDIT_ACK, PARAMETER_EDIT_STROBE, 14);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set ThermoCamera functionality active (HMI)
|
|
/// </summary>
|
|
/// <param name="enableTCam"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WTCamActiv(bool enableTCam)
|
|
{
|
|
CmsError libraryError = MEM_RWBoolean(W, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 1, ref enableTCam);
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set ThermoCamera mode
|
|
/// </summary>
|
|
/// <param name="enableTCam"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WTCamMode(bool enableTCam)
|
|
{
|
|
CmsError libraryError = MEM_RWBoolean(W, true, 0, TCAM_COMMW_DATA.MemType, TCAM_COMMW_DATA.Address, TCAM_COMMW_DATA.SubAddress, 0, ref enableTCam);
|
|
return libraryError;
|
|
}
|
|
|
|
public override CmsError PLC_WTerminateAssistedToolingProcedure()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WTerminateMovementProcedure(MOVEMENT_RESPONSE resp)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError PLC_WUserSoftKey(uint id)
|
|
{
|
|
// Check id range
|
|
if (id > USER_SOFTKEYS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Write strobe into memory --> false because is bitArray
|
|
CmsError libraryError = PLC_WStrobe(false, USER_SOFT_KEYS_ACK, USER_SOFT_KEYS_CLICKED, id);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// <summary>
|
|
/// Write Warmers channels load data
|
|
/// </summary>
|
|
/// <param name="newData"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerChSetpHmi(Dictionary<int, int> newData)
|
|
{
|
|
// memory area
|
|
byte[] newMem = new byte[newData.Count];
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// read actual data on memory...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
newMem = currMem.ToArray();
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
newMem[item.Key - 1] = (byte)item.Value;
|
|
}
|
|
// return as list...
|
|
currMem = newMem.ToList();
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWByteList(W, 0, RISC_CHP_DATA.MemType, RISC_CHP_DATA.Address, RISC_CHP_DATA.SubAddress, 0, RISC_CHP_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current Warmers Channels as enabled/disabled for working with thermo camera data
|
|
/// </summary>
|
|
/// <param name="newData"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerChTCamEnab(Dictionary<int, bool> newData)
|
|
{
|
|
// leggo DB664 x abilitazione ch alla termocamera
|
|
bool[] newMem = new bool[TCAM_CH_ENAB_DATA.Size * 8];
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// read actual data on memory...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// Convert int into to true/false array
|
|
BitArray bArray = new BitArray(currMem.ToArray());
|
|
bArray.CopyTo(newMem, 0);
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
newMem[item.Key - 1] = item.Value;
|
|
}
|
|
// return as list...
|
|
currMem = boolsToByteArray(newMem).ToList();
|
|
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWByteList(W, 0, TCAM_CH_ENAB_DATA.MemType, TCAM_CH_ENAB_DATA.Address, TCAM_CH_ENAB_DATA.SubAddress, 0, TCAM_CH_ENAB_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return libraryError;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current Warmers Channels Thermocam read (actual) value (°C)
|
|
/// </summary>
|
|
/// <param name="updtCh"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerChTCamTempAct(Dictionary<int, double> newData)
|
|
{
|
|
// valori in 1/10 di °C
|
|
int dataScale = 10;
|
|
// memory area
|
|
short[] newMem = new short[newData.Count];
|
|
// leggo DB625 x val Temp attuali
|
|
List<short> currMem = new List<short>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_ACT_DATA.MemType, TCAM_TEMP_ACT_DATA.Address, TCAM_TEMP_ACT_DATA.SubAddress, TCAM_TEMP_ACT_DATA.Size, ref currMem);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
newMem = currMem.ToArray();
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
// attenzione: effettua scalatura dati!
|
|
newMem[item.Key - 1] = (short)(dataScale * item.Value);
|
|
}
|
|
// return as list...
|
|
currMem = newMem.ToList();
|
|
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWShortList(W, 0, TCAM_TEMP_ACT_DATA.MemType, TCAM_TEMP_ACT_DATA.Address, TCAM_TEMP_ACT_DATA.SubAddress, TCAM_TEMP_ACT_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current Warmers Channels Temp REF Setpoints (1/10 °C)
|
|
/// </summary>
|
|
/// <param name="updtCh"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerChTCamTempSet(Dictionary<int, double> newData)
|
|
{
|
|
// valori in 1/10 di °C
|
|
int dataScale = 10;
|
|
// memory area
|
|
short[] newMem = new short[newData.Count];
|
|
// leggo DB624 x Setpoint Temp richiesti
|
|
List<short> currMem = new List<short>();
|
|
|
|
// leggo da PLC a array di byte di appoggio...
|
|
CmsError libraryError = MEM_RWShortList(R, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem);
|
|
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
newMem = currMem.ToArray();
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
// attenzione: effettua scalatura dati!
|
|
newMem[item.Key - 1] = (short)(dataScale * item.Value);
|
|
}
|
|
// return as list...
|
|
currMem = newMem.ToList();
|
|
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWShortList(W, 0, TCAM_TEMP_REQ_DATA.MemType, TCAM_TEMP_REQ_DATA.Address, TCAM_TEMP_REQ_DATA.SubAddress, TCAM_TEMP_REQ_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current Warmers Channels reflector's data
|
|
/// </summary>
|
|
/// <param name="updtCh"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerConfBoardEnabl(Dictionary<int, int> newData)
|
|
{
|
|
// memory area
|
|
byte[] newMem = new byte[newData.Count];
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// read actual data on memory...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_OCC_DATA.MemType, RISC_OCC_DATA.Address, RISC_OCC_DATA.SubAddress, 0, RISC_OCC_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
newMem = currMem.ToArray();
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
newMem[item.Key] = (byte)item.Value;
|
|
}
|
|
// return as list...
|
|
currMem = newMem.ToList();
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWByteList(W, 0, RISC_OCC_DATA.MemType, RISC_OCC_DATA.Address, RISC_OCC_DATA.SubAddress, 0, RISC_OCC_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current Warmers Channels min current data
|
|
/// </summary>
|
|
/// <param name="updtCh"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerConfMinCurr(Dictionary<int, double> newData)
|
|
{
|
|
// memory area
|
|
List<double> ListValue = new List<double>();
|
|
|
|
// read actual data on memory...
|
|
CmsError libraryError = MEM_RWDoubleList(R, 0, RISC_ICH_MIN_DATA.MemType, RISC_ICH_MIN_DATA.Address, RISC_ICH_MIN_DATA.SubAddress, RISC_ICH_MIN_DATA.Size, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
var newMem = ListValue.ToArray();
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
// 2020.07.21 fix perché channes 1 based, memory 0 based
|
|
newMem[item.Key - 1] = item.Value;
|
|
}
|
|
// return as list...
|
|
ListValue = newMem.ToList();
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWDoubleList(W, 0, RISC_ICH_MIN_DATA.MemType, RISC_ICH_MIN_DATA.Address, RISC_ICH_MIN_DATA.SubAddress, RISC_ICH_MIN_DATA.Size, ref ListValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set current Warmers Channels reflector's data
|
|
/// </summary>
|
|
/// <param name="updtCh"></param>
|
|
/// <returns></returns>
|
|
public override CmsError PLC_WWarmerConfRefl(Dictionary<int, int> newData)
|
|
{
|
|
// memory area
|
|
byte[] newMem = new byte[newData.Count];
|
|
List<byte> currMem = new List<byte>();
|
|
|
|
// read actual data on memory...
|
|
CmsError libraryError = MEM_RWByteList(R, 0, RISC_CFI_DATA.MemType, RISC_CFI_DATA.Address, RISC_CFI_DATA.SubAddress, 0, RISC_CFI_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
newMem = currMem.ToArray();
|
|
|
|
// update only given data...
|
|
foreach (var item in newData)
|
|
{
|
|
// algoritmo: valore = (val + 1) % 8, ovvero riflettore 0, 8, 16 --> 1, riflettore 1, 9, 17 --> 2
|
|
newMem[item.Key - 1] = (byte)((item.Value + 1) % 8);
|
|
}
|
|
// return as list...
|
|
currMem = newMem.ToList();
|
|
// scrivo sul PLC array di byte...
|
|
libraryError = MEM_RWByteList(W, 0, RISC_CFI_DATA.MemType, RISC_CFI_DATA.Address, RISC_CFI_DATA.SubAddress, 0, RISC_CFI_DATA.Size, ref currMem);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the process Active Alarms
|
|
public override CmsError PROC_RActiveAlarms(ushort procNumber, ref List<AlarmModel> alarms)
|
|
{
|
|
// FIXME TODO - fare guardando bitmap allarmi attivi
|
|
#if false
|
|
alarms = SiemensAlarms
|
|
.Where(x => x.Id >= IDMinChannel && x.Id <= IDMaxChannel && x.Parameters[0].Equals(procNumber.ToString()))
|
|
.Select(x =>
|
|
{
|
|
uint id = x.Instance == 1 ? (uint)x.Id : Convert.ToUInt32((x.Id & 0xffff) | (x.Instance << 24));
|
|
return new AlarmModel()
|
|
{
|
|
Id = id,
|
|
Message = x.Message,
|
|
IsWarning = false,
|
|
Process = procNumber,
|
|
DateTime = x.TimeStamp
|
|
};
|
|
})
|
|
.ToList();
|
|
#endif
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get the process Mode
|
|
public override CmsError PROC_RMode(ushort ProcNumber, ref PROC_MODE Mode)
|
|
{
|
|
//Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// FIXME TODO - fare guardando mappatura memoria stsato processo
|
|
|
|
#if false
|
|
// Try to get information
|
|
try
|
|
{
|
|
// Setup variables
|
|
DataSvc Data = HighPriorityDataSvc();
|
|
Item itemRead = new Item(NC_GENERIC_MODE_PATH + "[u" + ProcNumber + "]");
|
|
Item itemReadIncr = new Item(JOG_INCR_PATH + "[u" + ProcNumber + "]");
|
|
Item itemReadAdv = new Item(ADVANCED_JOG_PATH + "[u" + ProcNumber + "]");
|
|
|
|
// Read Data
|
|
Data.Read(itemRead);
|
|
Data.Read(itemReadIncr);
|
|
Data.Read(itemReadAdv);
|
|
|
|
// Save Data
|
|
Mode = ConvertToSTEPMode((uint)itemRead.Value, (uint)itemReadIncr.Value, (uint)itemReadAdv.Value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
#endif
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get 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;
|
|
}
|
|
|
|
public override CmsError PROC_RSelectedProcess(ref ushort procNumber)
|
|
{
|
|
if (SelectedProcess == 0)
|
|
return SELECTED_PROCESS_ERROR;
|
|
|
|
procNumber = SelectedProcess;
|
|
//CmsError libraryError;
|
|
//bool readValue = false;
|
|
|
|
//for (int i = 0; i < PROCESS_NUMBER; i++)
|
|
//{
|
|
// // Calculate bit address = ProcessBase + processId * 2
|
|
// int memoryAddress = SELECTED_PROCESS.SubAddress + i * (2);
|
|
// // Read memory from plc
|
|
// libraryError = MEM_RWBoolean(R, 0, SELECTED_PROCESS.MemType, SELECTED_PROCESS.Address, memoryAddress, 2, ref readValue);
|
|
// if (libraryError.IsError())
|
|
// return libraryError;
|
|
|
|
// if (readValue)
|
|
// {
|
|
// procNumber = (ushort)(i + 1);
|
|
// return NO_ERROR;
|
|
// }
|
|
//}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError PROC_RSelectedProcessData(int processId, ref SelectedProcessData processData)
|
|
{
|
|
if (processId <= 0)
|
|
return PROC_NOT_FOUND_ERROR;
|
|
|
|
// FIXME TODO - ha senso?
|
|
#if false
|
|
try
|
|
{
|
|
Item[] items = new Item[7]
|
|
{
|
|
new Item { Path = "/Channel/State/actTNumber[u" + processId + ",1]" }, // ActiveToolId
|
|
new Item { Path = "/Channel/State/actDNumber[u" + processId + ",1]" }, // OffsetId
|
|
new Item { Path = "/Channel/State/actFrameIndex[u" + processId + "]" }, // Origin
|
|
new Item { Path = "DB21.DBB4"}, // Work override
|
|
new Item { Path = "DB21.DBB5"}, // Rapid override,
|
|
new Item { Path = "/Channel/State/actFeedRateIpo[u" + processId + ", 1]"},
|
|
new Item { Path = "/Nck/Configuration/numCuttEdgeParams[1]"}, // Cutt Edge Params
|
|
};
|
|
|
|
// Read data
|
|
DataSvc dataSvc = new DataSvc();
|
|
dataSvc.Read(items);
|
|
|
|
short origin = 0;
|
|
// Convert SIEMENS enumerable to G(N) format es: G54
|
|
if (Convert.ToInt16(items[2].Value) > 0)
|
|
{
|
|
if (Convert.ToInt16(items[1].Value) >= 5)
|
|
origin = (short)(Convert.ToInt16(items[2].Value) + 500);
|
|
else
|
|
origin = (short)(Convert.ToInt16(items[2].Value) + 53);
|
|
}
|
|
|
|
OffsetModel offset = new OffsetModel();
|
|
|
|
//Read the ID of the Tool & Edge
|
|
short actualToolId = Convert.ToInt16(items[0].Value);
|
|
short actualEdgeId = Convert.ToInt16(items[1].Value);
|
|
short numCuttEdgeParams = Convert.ToInt16(items[6].Value);
|
|
int offsetEdge = (actualEdgeId - 1) * numCuttEdgeParams;
|
|
|
|
if (actualToolId != 0 && actualEdgeId != 0)
|
|
{
|
|
//Setup the items for the tools. Must be read only this value
|
|
Item[] itemsToolEdge = new Item[4]
|
|
{
|
|
new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 3) + "]" }, // $TC_DP3
|
|
new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 6) + "]" }, // $TC_DP6
|
|
new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 12) + "]" }, // $TC_DP12
|
|
new Item { Path = "/Tool/Compensation/edgeData[u1,c"+ actualToolId +","+ (offsetEdge + 15) + "]" } // $TC_DP15
|
|
};
|
|
|
|
dataSvc.Read(itemsToolEdge);
|
|
|
|
offset = new OffsetModel()
|
|
{
|
|
Id = actualEdgeId,
|
|
Length = Convert.ToDouble(itemsToolEdge[0].Value),
|
|
Radius = Convert.ToDouble(itemsToolEdge[1].Value),
|
|
WearLength = Convert.ToDouble(itemsToolEdge[2].Value),
|
|
WearRadius = Convert.ToDouble(itemsToolEdge[3].Value),
|
|
RealLength = Convert.ToDouble(itemsToolEdge[0].Value) + Convert.ToDouble(itemsToolEdge[2].Value),
|
|
RealRadius = Convert.ToDouble(itemsToolEdge[1].Value) + Convert.ToDouble(itemsToolEdge[3].Value)
|
|
};
|
|
|
|
/* Other Method. Find it in the Database of the Tools... Too SLow? (Nicola Carminati 08/08/19)
|
|
// Find edge
|
|
EdgeModel edge = ToolTableData.Where(x => x.Id == Convert.ToInt16(items[0].Value))
|
|
.FirstOrDefault()
|
|
.EdgesData.Where(x => x.Id == Convert.ToInt16(items[1].Value))
|
|
.FirstOrDefault();
|
|
|
|
//Find the Type of the Tool
|
|
SiemensEdgesConfiguration toolEdgesConfig = new SiemensEdgesConfiguration();
|
|
List<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;
|
|
}
|
|
|
|
// Get the process status
|
|
public override CmsError PROC_RStatus(ushort ProcNumber, ref PROC_STATUS Status)
|
|
{
|
|
// Check if the NC is Connected
|
|
CmsError libraryError = CheckConnection();
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
// FIXME TODO - fare guardando mappatura variabili status
|
|
#if false
|
|
// Try to get information
|
|
try
|
|
{
|
|
// Setup variables
|
|
DataSvc Data = HighPriorityDataSvc();
|
|
Item itemRead = new Item(NC_GENERIC_STATE_PATH + "[u" + ProcNumber + "]");
|
|
|
|
// Read Data
|
|
Data.Read(itemRead);
|
|
|
|
// Save Data
|
|
Status = ConvertToSTEPStatus((uint)itemRead.Value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return ManageException(ex);
|
|
}
|
|
#endif
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Get process part program data
|
|
public override CmsError PROC_RStatusAndData(ushort procNumber, ref ProcessDataModel processData)
|
|
{
|
|
processData.Id = procNumber;
|
|
CmsError libraryError = NO_ERROR;
|
|
#if false
|
|
// Read part program name
|
|
libraryError = PROC_RSelectedPPName(procNumber, ref processData.PartProgramName);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
#endif
|
|
|
|
// FIXME TODO --> forzato tutto a true... eventualmente rivedere in futuro x processo caricatore vs processo principale
|
|
bool forceValues = true;
|
|
|
|
if (forceValues)
|
|
{
|
|
processData.Visible = true;
|
|
processData.Type = "WORK";
|
|
processData.IsSelected = true;
|
|
processData.IsInAlarm = false;
|
|
processData.CanLoadProgram = true;
|
|
processData.Status = "RUN";
|
|
processData.Reps = 0;
|
|
}
|
|
else
|
|
{
|
|
int readValue = 0;
|
|
|
|
// Read processes status from memory
|
|
libraryError = MEM_RWInteger(R, 0, PROCESS_STATUS.MemType, PROCESS_STATUS.Address, PROCESS_STATUS.SubAddress + ((procNumber - 1) * 2), ref readValue);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
byte[] bytes = BitConverter.GetBytes(readValue);
|
|
|
|
// Convert Byte into true/false array
|
|
BitArray bits = new BitArray(new byte[] { bytes[0] }); // 1st byte -> 0 : Proccess type (AUX-WORK), 1: Process in alarm status, 2: Run, 3: Hold, 4: Read, 5: PartProgramVisible
|
|
|
|
// Get part program info visibility
|
|
processData.Visible = bits[0];
|
|
|
|
// Populate response structure
|
|
processData.Type = bits[1] ? "WORK" : "AUX";
|
|
processData.IsSelected = bits[2];
|
|
processData.IsInAlarm = bits[3];
|
|
processData.CanLoadProgram = bits[4];
|
|
|
|
// Choose process status
|
|
if (bytes[1] == 1)
|
|
processData.Status = "HOLD";
|
|
else
|
|
{
|
|
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_WSelectProcess(ushort procNumber)
|
|
{
|
|
CmsError libraryError;
|
|
byte processNum = (byte)procNumber;
|
|
|
|
// Check parameter
|
|
if (processNum > MAX_PROCESS_NUMBER)
|
|
return INCORRECT_PARAMETERS_ERROR;
|
|
|
|
// Write process number
|
|
libraryError = MEM_RWByte(W, true, 0, SELECT_PROCESS.MemType, SELECT_PROCESS.Address, SELECT_PROCESS.SubAddress, 0, ref processNum);
|
|
if (libraryError.IsError())
|
|
return libraryError;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RAdatpivePathStep(ref Byte step)
|
|
{
|
|
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_RConfiguration(ref ToolTableConfiguration config)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RFamilyData(ref List<FamilyModel> families)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineAction(ref MagazineActionModel magazineAction)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineBlock(ref List<int> ids)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineConfig(ref List<NcMagazineConfigModel> config)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazinePositions(ref List<PositionModel> positions)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RMagazineStatus(ref Dictionary<int, bool> magazineStatus)
|
|
{
|
|
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_ROffset(short offsetId, ref OffsetModel offset)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RShanksData(ref List<ShankModel> shanksData)
|
|
{
|
|
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_RToolsData(ref List<SiemensToolModel> toolTable)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_RUpdatedToolsData(ref Dictionary<int, byte> updatedStatus, ref Dictionary<int, uint> updatedLives, ref Dictionary<int, ushort> updatedPresetting, ref Dictionary<int, ushort> updatedDressing)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAbortBallufTablet()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAdatpivePathStep(Byte step)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WAddEdge(int toolId, ref EdgeModel edge)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
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_WAddTool(ref SiemensToolModel tool)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteEdge(int toolId, int edgeId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteFamily(string name)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteShank(int id)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WDeleteTool(int id)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WEmptyBallufTablet(SiemensToolModel tool)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WEmptyBallufTabletAdditionalData(SiemensToolModel tool)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WFreeMagazines()
|
|
{
|
|
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_WLoadToolIntoShank(int shankId, int positionId, int toolId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WOffset(short offsetId, ref OffsetModel offset)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
public override CmsError TOOLS_WOptions(ToolManagerOptionsModel options)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WRestoreBackup()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStartEditData()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStartEditTooling(int magazineId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
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_WStopEditData()
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WStopEditTooling(int magazineId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUnloadToolFromMagazine(int magazineId, int positionId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUnloadToolFromShank(int shankId, int positionId)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateEdge(int toolId, ref EdgeModel newEdge)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateFamilies(List<NcFamilyModel> list)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateFamilyData(string oldName, string newName)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateMagazinePositions(List<NcMagazinePositionModel> list)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdatePosition(PositionModel position)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateShank(ref ShankModel shank)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateShanks(List<NcShankModel> list)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateTool(ref SiemensToolModel tool)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
public override CmsError TOOLS_WUpdateTools(List<NcToolModel> list)
|
|
{
|
|
return FUNCTION_NOT_ALLOWED_ERROR;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Classes
|
|
|
|
/// <summary>
|
|
/// Oggetto Modulo Blocco da PLC
|
|
/// </summary>
|
|
protected class PlcModBlock
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Deserializzazione da byte ad oggetto Param
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
public PlcModBlock(byte[] rawData)
|
|
{
|
|
// converto i dati da byte grezzi ai 3 componenti...
|
|
Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray());
|
|
EstimDuration = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray());
|
|
EstimDelay = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray());
|
|
PrevId_01 = S7.Net.Types.Int.FromByteArray(rawData.Skip(12).Take(2).ToArray());
|
|
PrevId_02 = S7.Net.Types.Int.FromByteArray(rawData.Skip(14).Take(2).ToArray());
|
|
PrevId_03 = S7.Net.Types.Int.FromByteArray(rawData.Skip(16).Take(2).ToArray());
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
public int EstimDelay { get; set; } = 0;
|
|
public int EstimDuration { get; set; } = 0;
|
|
public short Id { get; set; } = 0;
|
|
public short PrevId_01 { get; set; } = 0;
|
|
public short PrevId_02 { get; set; } = 0;
|
|
public short PrevId_03 { get; set; } = 0;
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Converte un singolo item in un array di byte per scrittura su PLC S7
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte[] convertToByte()
|
|
{
|
|
byte[] answ = new byte[18];
|
|
Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(EstimDuration), 0, answ, 2, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(EstimDelay), 0, answ, 6, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_01), 0, answ, 12, 2);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_02), 0, answ, 14, 2);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(PrevId_03), 0, answ, 16, 2);
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
|
|
/// <summary>
|
|
/// Oggetto Modulo Blocco RT da PLC
|
|
/// </summary>
|
|
protected class PlcModBlockRT
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Deserializzazione da byte ad oggetto ParamRT
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
public PlcModBlockRT(byte[] rawData)
|
|
{
|
|
// converto i dati da byte grezzi ai 3 componenti...
|
|
Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray());
|
|
ActualDuration = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray());
|
|
ActualDelay = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray());
|
|
// sono in realtà BIT STRUC --> reverse!
|
|
Stato = S7.Net.Types.Word.FromByteArray(rawData.Skip(10).Take(2).Reverse().ToArray());
|
|
// calcolo bit...
|
|
Visible = (Stato & 1) == 1;
|
|
Running = (Stato & 2) == 2;
|
|
HasError = (Stato & 4) == 4;
|
|
Terminated = (Stato & 8) == 8;
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Properties
|
|
|
|
private ushort Stato { get; set; } = 0;
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Public Properties
|
|
|
|
public int ActualDelay { get; set; } = 0;
|
|
public int ActualDuration { get; set; } = 0;
|
|
public bool HasError { get; set; }
|
|
public short Id { get; set; } = 0;
|
|
public bool Running { get; set; }
|
|
public bool Terminated { get; set; } = false;
|
|
public bool Visible { get; set; }
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Converte un singolo item in un array di byte per scrittura su PLC S7
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte[] convertToByte()
|
|
{
|
|
// convero stato dai bit...
|
|
Stato = 0;
|
|
Stato += (ushort)(Visible ? 1 : 0);
|
|
Stato += (ushort)(Running ? 2 : 0);
|
|
Stato += (ushort)(HasError ? 4 : 0);
|
|
Stato += (ushort)(Terminated ? 8 : 0);
|
|
byte[] answ = new byte[12];
|
|
Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ActualDuration), 0, answ, 2, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ActualDelay), 0, answ, 6, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.Word.ToByteArray(Stato), 0, answ, 10, 1);
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
|
|
/// <summary>
|
|
/// Oggetto Parametro da PLC
|
|
/// </summary>
|
|
protected class PlcParam
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Deserializzazione da byte ad oggetto Param
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
public PlcParam(byte[] rawData)
|
|
{
|
|
// converto i dati da byte grezzi ai 3 componenti...
|
|
Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray());
|
|
SetpointHMI = S7.Net.Types.DInt.FromByteArray(rawData.Skip(2).Take(4).ToArray());
|
|
SetpointPLC = S7.Net.Types.DInt.FromByteArray(rawData.Skip(6).Take(4).ToArray());
|
|
ValMax = S7.Net.Types.DInt.FromByteArray(rawData.Skip(10).Take(4).ToArray());
|
|
ValMin = S7.Net.Types.DInt.FromByteArray(rawData.Skip(14).Take(4).ToArray());
|
|
UnitMeasure = S7.Net.Types.Word.FromByteArray(rawData.Skip(18).Take(2).ToArray());
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
public short Id { get; set; } = 0;
|
|
public int SetpointHMI { get; set; } = 0;
|
|
public int SetpointPLC { get; set; } = 0;
|
|
public ushort UnitMeasure { get; set; } = 0;
|
|
public int ValMax { get; set; } = 0;
|
|
public int ValMin { get; set; } = 0;
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Converte un singolo item in un array di byte per scrittura su PLC S7
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte[] convertToByte()
|
|
{
|
|
byte[] answ = new byte[20];
|
|
Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(SetpointHMI), 0, answ, 2, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(SetpointPLC), 0, answ, 6, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValMax), 0, answ, 10, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValMin), 0, answ, 14, 4);
|
|
Buffer.BlockCopy(S7.Net.Types.Word.ToByteArray(UnitMeasure), 0, answ, 18, 2);
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
|
|
/// <summary>
|
|
/// Oggetto Parametro RT da PLC
|
|
/// </summary>
|
|
protected class PlcParamRT
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Deserializzazione da byte ad oggetto ParamRT
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
public PlcParamRT(byte[] rawData)
|
|
{
|
|
// converto i dati da byte grezzi ai 3 componenti...
|
|
Id = S7.Net.Types.Int.FromByteArray(rawData.Skip(0).Take(2).ToArray());
|
|
ValueAct = S7.Net.Types.DInt.FromByteArray(rawData.Skip(4).Take(4).ToArray());
|
|
Visible = S7.Net.Types.Boolean.GetValue(rawData[2], 0);
|
|
Enabled = S7.Net.Types.Boolean.GetValue(rawData[2], 1);
|
|
HasError = S7.Net.Types.Boolean.GetValue(rawData[2], 2);
|
|
#if false
|
|
// calcolo bit...
|
|
Stato = S7.Net.Types.Word.FromByteArray(rawData.Skip(2).Take(2).Reverse().ToArray());
|
|
Visible = (Stato & 1) == 1;
|
|
Enabled = (Stato & 2) == 2;
|
|
HasError = (Stato & 4) == 4;
|
|
#endif
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Properties
|
|
|
|
private byte Stato { get; set; } = 0;
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Public Properties
|
|
|
|
public bool Enabled { get; set; }
|
|
public bool HasError { get; set; }
|
|
public short Id { get; set; } = 0;
|
|
public int ValueAct { get; set; } = 0;
|
|
public bool Visible { get; set; }
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Converte un singolo item in un array di byte per scrittura su PLC S7
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte[] convertToByte()
|
|
{
|
|
// convero stato dai bit...
|
|
Stato = 0;
|
|
Stato += (byte)(Visible ? 1 : 0);
|
|
Stato += (byte)(Enabled ? 2 : 0);
|
|
Stato += (byte)(HasError ? 4 : 0);
|
|
byte[] answ = new byte[8];
|
|
Buffer.BlockCopy(S7.Net.Types.Int.ToByteArray(Id), 0, answ, 0, 2);
|
|
Buffer.BlockCopy(S7.Net.Types.Byte.ToByteArray(Stato), 0, answ, 2, 1);
|
|
Buffer.BlockCopy(S7.Net.Types.DInt.ToByteArray(ValueAct), 0, answ, 4, 4);
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
|
|
#endregion Protected Classes
|
|
|
|
//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.);
|
|
// }
|
|
//}
|
|
}
|
|
} |