diff --git a/IOB-UT-NEXT/Enums.cs b/IOB-UT-NEXT/Enums.cs index cf69d0fa..b5ebaa90 100644 --- a/IOB-UT-NEXT/Enums.cs +++ b/IOB-UT-NEXT/Enums.cs @@ -330,6 +330,11 @@ namespace IOB_UT_NEXT /// OpcUaEwon, + /// + /// Adapter OPC-UA per Ewon x BLM / Mecart + /// + OpcUaEwonBLM, + /// /// Adapter OPC-UA per Ewon x Monti / Tenditalia /// diff --git a/IOB-UT-NEXT/ToMapo.cs b/IOB-UT-NEXT/ToMapo.cs index cc16d939..a810223e 100644 --- a/IOB-UT-NEXT/ToMapo.cs +++ b/IOB-UT-NEXT/ToMapo.cs @@ -495,13 +495,21 @@ namespace IOB_UT_NEXT /// /// Conf Gestione WatchDog /// - public WatchDogConf WatchDog {get;set;} = new WatchDogConf(); + public WatchDogConf WatchDog { get; set; } = new WatchDogConf(); /// /// Conf gestione setup macchina /// public MachineSetupConf SetupConf { get; set; } = new MachineSetupConf(); + public UserIdent Identity { get; set; } = new UserIdent(); + #endregion Public Properties } + + public class UserIdent + { + public string UserName { get; set; } = ""; + public string Passwd { get; set; } = ""; + } } \ No newline at end of file diff --git a/IOB-WIN-NEXT/AdapterForm.cs b/IOB-WIN-NEXT/AdapterForm.cs index 96b4c832..d4bf4a68 100644 --- a/IOB-WIN-NEXT/AdapterForm.cs +++ b/IOB-WIN-NEXT/AdapterForm.cs @@ -1218,6 +1218,11 @@ namespace IOB_WIN_NEXT start.Enabled = true; break; + case tipoAdapter.OpcUaEwonBLM: + iobObj = new IobOpcUaEwonBLM(this, IOBConf); + start.Enabled = true; + break; + case tipoAdapter.OpcUaEwonMonti: iobObj = new IobOpcUaEwonMonti(this, IOBConf); start.Enabled = true; diff --git a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini index cf107e9e..6558e382 100644 --- a/IOB-WIN-NEXT/DATA/CONF/MAIN.ini +++ b/IOB-WIN-NEXT/DATA/CONF/MAIN.ini @@ -72,6 +72,6 @@ CLI_INST=SteamWareSim ;STARTLIST=FP_TR2 ;STARTLIST=PING ;STARTLIST=SIM_PIZ03 -STARTLIST=PING +STARTLIST=MECART_80 MAXCNC=10 \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/MECART_80.ini b/IOB-WIN-NEXT/DATA/CONF/MECART_80.ini new file mode 100644 index 00000000..00db7ea5 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/MECART_80.ini @@ -0,0 +1,71 @@ +;Configurazione IOB-WIN +[IOB] +;Centro di lavoro OpcUa +CNCTYPE=OpcUaEwonBLM +PING_MS_TIMEOUT=500 + +[MACHINE] +VENDOR=BLM +MODEL=Piegatubi + +[CNC] +IP=192.168.1.80 +PORT=4840 +GETPRGNAME=true + +[SERVER] +MPIP=http://192.168.1.66 +MPURL=/MP/IO +CMDBASE=/IOB/input/ +CMDFLOG=/IOB/flog/ +CMDALIVE=/IOB +CMDENABLED=/IOB/enabled/ +CMDADV1=?valore= +CMDREBO=/sendReboot.aspx?idxMacchina= + +[MEMORY] +ADDR_READ=DB9999.DBB0 +ADDR_WRITE=DB9999.DBB0 +SIZE_READ=0 +SIZE_WRITE=0 +;BIT0=CONN +;BIT1=DB60.DBB1 +;BIT2=PZCOUNT.STD.DB700.DBW22 +;BIT3=DB60.DBB3 +;BIT4=DB60.DBB4 + + +[BLINK] +;MAX_COUNTER_BLINK = 30 +MAX_COUNTER_BLINK = 15 +;bit0 = 0 +;bit1 = 0 +;bit2 = 1 +;bit3 = 1 +;bit4 = 1 +;bit5 = 0 +;bit6 = 0 +;bit7 = 0 +BLINK_FILT=0 +;BLINK_FILT=28 + +[OPTPAR] +AUTO_CHANGE_ODL=false +CHANGE_ODL_MODE=TIME +CHANGE_ODL_HOURS=24 +CHANGE_ODL_IDLE_MIN=5 +PZCOUNT_MODE=OPC +DISABLE_PZCOUNT=FALSE +ENABLE_SEND_PZC_BLOCK=TRUE +MIN_SEND_PZC_BLOCK=0 +MAX_SEND_PZC_BLOCK=100 +ENABLE_DYN_DATA=FALSE +FORCE_DYN_DATA=TRUE +ENABLE_DATA_FILTER=TRUE +ENABLE_CLI_RESTART=TRUE + +; conf parametri memoria READ/WRITE +OPC_PARAM_CONF=MECART_80.json + +[BRANCH] +NAME=master \ No newline at end of file diff --git a/IOB-WIN-NEXT/DATA/CONF/MECART_80.json b/IOB-WIN-NEXT/DATA/CONF/MECART_80.json new file mode 100644 index 00000000..cf3cb2c8 --- /dev/null +++ b/IOB-WIN-NEXT/DATA/CONF/MECART_80.json @@ -0,0 +1,93 @@ +{ + "BrowseFullVal": "ns=4;i=5001", + "BrowseNSIndex": 4, + "BrowseValue": 5001, + "keyPartCount": "PartDone(0)", + "keyPartReq": "PartToDo(0)", + "keyPartId": "", + "keyProgName": "PartName(0)", + "keyRunMode": "", + "pingAsPowerOn": false, + "Identity": { + "UserName": "CUSTOMER", + "Passwd": "BLM" + }, + "condWork": [ + { + "keyName": "OperativeModeCN", + "targetValue": "0" + } + ], + "condPowerOn": { + "checkMode": "AND", + "checkList": [ + { + "keyName": "EmergencyState", + "targetValue": "0" + } + ] + }, + "condReady": { + "checkMode": "AND", + "checkList": [] + }, + "condManual": { + "checkMode": "AND", + "checkList": [ + { + "keyName": "OperativeModeCN", + "targetValue": "1" + } + ] + }, + "condEStop": { + "checkMode": "AND", + "checkList": [ + { + "keyName": "EmergencyState", + "targetValue": "1" + } + ] + }, + "condError": { + "checkMode": "AND", + "checkList": [ + { + "keyName": "MachineStatus(0)", + "targetValue": "1" + } + ] + }, + "condCountEnabled": { + "checkMode": "AND", + "checkList": [] + }, + "condWarmUpCoolDown": { + "checkMode": "OR", + "checkList": [] + }, + "condwarning": { + "checkMode": "AND", + "checkList": [] + }, + "condSetup": { + "checkMode": "AND", + "checkList": [ + { + "keyName": "OperativeModeCN", + "targetValue": "3" + } + ] + }, + "fluxLogVeto": [], + "itemTranslation": { + "avail": "Machine Available", + "rstat": "Execution Mode", + "mode": "Controller Mode", + "PartName(0)": "Program Name", + "PartDone(0)": "Pezzi Prodotti", + "PartToDo(0)": "Qta Richiesta", + "fdovrd": "PATH FEED OVERRIDE", + "rovrd": "PATH RAPID OVERRIDE" + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj index 7dbd5c67..ab3afa88 100644 --- a/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj +++ b/IOB-WIN-NEXT/IOB-WIN-NEXT.csproj @@ -182,6 +182,7 @@ VersGen.cs + @@ -472,6 +473,12 @@ Always + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/IOB-WIN-NEXT/IobOpcUa.cs b/IOB-WIN-NEXT/IobOpcUa.cs index 51c3c71a..3a2d6da8 100644 --- a/IOB-WIN-NEXT/IobOpcUa.cs +++ b/IOB-WIN-NEXT/IobOpcUa.cs @@ -316,10 +316,11 @@ namespace IOB_WIN_NEXT await application.CheckApplicationInstanceCertificate(silent: false, minimumKeySize: 0).ConfigureAwait(false); lgInfo($"Chiamata UAClient con configurazione standard: {application.ApplicationConfiguration.ApplicationName}"); - UA_ref = new UAClient(application.ApplicationConfiguration, cIobConf.codIOB, isVerboseLog, ClientBase.ValidateResponse); + UA_ref = new UAClient(application.ApplicationConfiguration, cIobConf.codIOB, opcUaParams.Identity.UserName, opcUaParams.Identity.Passwd, isVerboseLog, ClientBase.ValidateResponse); lgInfo($"Chiamata apertura OpcUa Client: {cIobConf.cncIpAddr}:{port}"); UA_ref.ServerUrl = $"opc.tcp://{cIobConf.cncIpAddr}:{port}"; + var task = Task.Run(async () => { return await UA_ref.ConnectAsync().ConfigureAwait(false); @@ -748,7 +749,7 @@ namespace IOB_WIN_NEXT List nodes2Write = new List(); nodes2Write.Add(commWriteVal); UA_ref.WriteNodes(nodes2Write); - lgInfo("Effettuata scrittura WatchDog"); + lgDebug("Effettuata scrittura WatchDog"); } catch (Exception exc) { @@ -807,11 +808,11 @@ namespace IOB_WIN_NEXT string jsonData = reader.ReadToEnd().Replace("\n", "").Replace("\r", ""); if (!string.IsNullOrEmpty(jsonData)) { - lgInfo($"File json composto da {jsonData.Length} caratteri"); + lgDebug($"File json composto da {jsonData.Length} caratteri"); try { opcUaParams = JsonConvert.DeserializeObject(jsonData); - lgInfo($"Decodifica aree OpcUaParamConf: trovati {opcUaParams.paramsEndThresh.Count} valori paramsEndThresh"); + lgDebug($"Decodifica aree OpcUaParamConf: trovati {opcUaParams.paramsEndThresh.Count} valori paramsEndThresh"); // sistemo se ci sono dati memMap... memMap = new plcMemMap(); if (opcUaParams.mMapWrite != null) diff --git a/IOB-WIN-NEXT/IobOpcUaEwonBLM.cs b/IOB-WIN-NEXT/IobOpcUaEwonBLM.cs new file mode 100644 index 00000000..f6f141d8 --- /dev/null +++ b/IOB-WIN-NEXT/IobOpcUaEwonBLM.cs @@ -0,0 +1,110 @@ +using MapoSDK; +using Newtonsoft.Json; +using Opc.Ua; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.NetworkInformation; +using System.Text; +using System.Threading.Tasks; + +namespace IOB_WIN_NEXT +{ + public class IobOpcUaEwonBLM : IobOpcUaEwon + { + #region Protected Fields + + + #endregion Protected Fields + + #region Public Constructors + + /// + /// Estende l'init della classe base, impiegando il pacchetto Nuget OPC-UA foundation con la gestione specifica per EWON (es Monti, Tenditalia) + /// https://github.com/OPCFoundation/UA-.NETStandard + /// + /// + /// + public IobOpcUaEwonBLM(AdapterForm caller, IobConfiguration IOBConf) : base(caller, IOBConf) + { + lgInfo("Init Ewon versione BLM (Mecart)"); + + // inizializzo classe base... + if (!string.IsNullOrEmpty(getOptPar("CHANGE_ODL_MODE"))) + { + CHANGE_ODL_MODE = getOptPar("CHANGE_ODL_MODE"); + } + sendKeyRichiesta = true; + } + + /// + /// Effettua vera scrittura parametri + /// + /// + protected override void plcWriteParams(ref List updatedPar) + { + base.plcWriteParams(ref updatedPar); + + // se DEVO gestire setup Mecolpress... + if (opcUaParams.SetupConf.SetupMode == IOB_UT_NEXT.MachineSetupMode.MECOLPRESS) + { + List nodes2Write = new List(); + // ora controllo la specifica condizione Mecolpress x il setup SE i parametri FOSSERO quelli di setup... + dataConf currMem = null; + // faccio un check tra i valori in memoria che devono corrispondere e se NON corrispondono --> metto valore in scrittura... + bool needWrite = false; + int numDiff = 0; + foreach (var item in opcUaParams.SetupConf.checkParList) + { + // cerco la memoria corrispondente... + var memorieMes = dataItemMem.Where(x => x.Key.Contains(item.Key)).ToList(); + var memorieMac = dataItemMem.Where(x => x.Key.Contains(item.Value)).ToList(); + // se ho trovato qualcosa verifico se corrispondono... + if (memorieMes.Count > 0 && memorieMes.Count > 0) + { + // controllo primo record con primo record + if (memorieMes.FirstOrDefault().Value.value != memorieMac.FirstOrDefault().Value.value) + { + numDiff++; + } + } + } + + // ciclo le condizioni di uscita + foreach (var item in opcUaParams.SetupConf.writeParAction) + { + WriteValue commWriteVal = new WriteValue(); + commWriteVal.NodeId = new NodeId(item.TargetParam); + commWriteVal.AttributeId = Attributes.Value; + commWriteVal.Value = new DataValue(); + // se ho differenze --> scrivo richiesta attrezzaggio... + if (numDiff > 0) + { + commWriteVal.Value.Value = item.TargetValNotEqual; + } + else + { + commWriteVal.Value.Value = item.TargetValEqual; + } + + // accodo x scrittura + nodes2Write.Add(commWriteVal); + lgInfo($"richiesta scrittura valore | nodeId: {commWriteVal.NodeId } | targetPar: {item.TargetParam} | val {commWriteVal.Value.Value}"); + } + + // x ora NON eseguo + if (opcUaParams.SetupConf.EnableAdvSetup) + { + // ora scrivo! + if (nodes2Write.Count > 0) + { + UA_ref.WriteNodes(nodes2Write); + } + } + } + } + + #endregion Public Constructors + + } +} \ No newline at end of file diff --git a/IOB-WIN-NEXT/UAClient.cs b/IOB-WIN-NEXT/UAClient.cs index 99f016f7..9229da4f 100644 --- a/IOB-WIN-NEXT/UAClient.cs +++ b/IOB-WIN-NEXT/UAClient.cs @@ -83,6 +83,12 @@ namespace IOB_WIN_NEXT protected static Logger lg; protected static bool isLogVerbose = false; + + /// + /// The user identity to use when creating the session. + /// + public IUserIdentity CurrUserIdentity { get; set; } = new UserIdentity(); + #endregion Protected Fields #region Public Constructors @@ -90,11 +96,19 @@ namespace IOB_WIN_NEXT /// /// Initializes a new instance of the UAClient class. /// - public UAClient(ApplicationConfiguration configuration, string codIOB, bool verboseLog, Action validateResponse) + public UAClient(ApplicationConfiguration configuration, string codIOB, string user, string pwd, bool verboseLog, Action validateResponse) { m_validateResponse = validateResponse; currIob = codIOB; lg = LogManager.GetCurrentClassLogger(); + if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(pwd)) + { + CurrUserIdentity = new UserIdentity(user, pwd); + } + else + { + CurrUserIdentity = new UserIdentity(); + } isLogVerbose = verboseLog; m_configuration = configuration; m_configuration.CertificateValidator.CertificateValidation += CertificateValidation; @@ -212,7 +226,7 @@ namespace IOB_WIN_NEXT lg.Factory.Configuration.Variables["codIOB"] = currIob; //if (isLogVerbose) //{ - lg.Info(message); + lg.Info(message); //} } @@ -416,7 +430,7 @@ namespace IOB_WIN_NEXT false, m_configuration.ApplicationName, 30 * 60 * 1000, - new UserIdentity(), + CurrUserIdentity, null );