Adding and Configuring an OPCClient DIObject using GRAccess

by Klaus Graefensteiner 3/11/2008 2:43:00 AM

Introduction

The GRAccess toolkit enables developers to automate activities that users normally perform manually using the Industrial Application Server Integrated Development Environment (IDE). This blog post describes how to create and configure a derived template of the OPCClient DIObject using a C# console application.

Prerequisites

To execute the GRAccess sample application that is described in this document, you will need the following prerequisites:

  1. Visual Studio 2005
  2. Industrial Application Server 2.1 or higher
  3. DASABTCP DAServer or any other OPC Server

Using the IDE to configure the OPCClient DIObject

First create a derived template of the OPCClient DIObject. Give the new derived template the name "$OPCClient_02" and open the editor of the template.

OPCClient template editor in IDE

In the "General" tab of the editor set the Server node to local host and select a registered OPC Server in the Server name combo box. Then switch to the Scan Group editor tab.

OPCClient ScanGroup editor

In the Scan Group tab add a new Scan Group called "Group1". Then select "Group1". Add two Attributes and name them "Counter_1" and "Counter_2". Assign the Item Reference "N100:1" to "Counter_1" and "N200:1" to "Counter_2". Then save and close the object.

 

What happened under the hood?

This paragraph describes in GRAccess API terms what happened under the hood during the configuration of the OPCClient DIObject:

Configure the common attributes

Query the Galaxies and Login
   1: Galaxies = GR.QueryGalaxies(GRMachineName);
   2: G = Galaxies[GalaxyName];
   3: G.Login(UserName, Password);
Get the $OPCClient template and derive a new template
   1: string[] Names = { "$OPCClient" };
   2: Objects = G.QueryObjectsByName(EgObjectIsTemplateOrInstance.gObjectIsTemplate, ref Names);
   3: T = (ITemplate)Objects[1];
   4: Parent = T.CreateTemplate(OPCClientTemplateName, true);
Checkout template
   1: Parent.CheckOut();
Configure ServerNode and ServerName attributes
   1: MxValue v = new MxValueClass();
   2: //Configure computer name of OPCServer
   3: v.PutString(OPCServerComputer);
   4: Parent.Attributes["ServerNode"].SetValue(v);
   5: //Configure OPC server name
   6: v.PutString(OPCServerName);
   7: Parent.Attributes["ServerName"].SetValue(v);
Adding ScanGroup and an attribute array of items
   1: //Configure OPCGroup name
   2: v.PutString(OPCGroupName);
   3: Parent.Attributes["_ScanGroupAdd"].SetValue(v);
   4: //Add list of alias names to Group1
   5: a.Empty();
   6: v.PutString(OPCItemAttributeName1);
   7: a.PutElement(1, v);
   8: v.PutString(OPCItemAttributeName2);
   9: a.PutElement(2, v);
  10: Parent.Attributes[OPCGroupName + "._ItemAdd"].SetValue(a);

 ScanGroup attribute

Save and CheckIn
   1: Parent.Save();
   2: Parent.CheckIn("");

Configure item attribute alias names

The configuration of the item alias mapping table is the tricky part of this procedure, because the attribute name to item association is stored as XML string in an attribute called [ScanGroupName].AliasDatabase. The ArchestrA item attributes are XML elements in this XML file and the alias names are XML attribute of the item elements. To modify the mapping the XML string needs to be retrieved from the attribute, the XML nodes need to be modified and then the modified XML string copied back into the original ArchestrA attribute.

AliasDatabase XML String

Get Group1.AliasDatabase XML
   1: v = Parent.Attributes[OPCGroupName + ".AliasDatabase"].value;
   2: string ItemDBXMLString = v.GetString();
   3: //Create an XML document instance, and load XML data from AliasDatabase attribute
   4: XmlDocument doc = new XmlDocument();
   5: System.IO.StringReader SR = new System.IO.StringReader(ItemDBXMLString);
   6: System.Xml.XmlTextReader TR = new System.Xml.XmlTextReader(SR);
   7: doc.Load(TR);
Use XPath to modify item names in XML
   1: //XPath query to the actual items
   2: XmlNodeList nodeList = doc.SelectNodes("/ItemsList/Item");
   3: //Modify items list to point to the actual item names
   4: XmlNode Item1 = nodeList[0];
   5: Item1.Attributes["Name"].Value = OPCItemName1;
   6: XmlNode Item2 = nodeList[1];
   7: Item2.Attributes["Name"].Value = OPCItemName2;
   8: string NewItemDBXMLString = doc.OuterXml;
Checkout template
   1: Parent.CheckOut();
Change Group1.AliasDatabase attribute with new XML
   1: v.Empty();
   2: v.PutString(NewItemDBXMLString);
   3: Parent.Attributes[OPCGroupName +".AliasDatabase"].SetValue(v);
Save and CheckIn
   1: Parent.Save();
   2: Parent.CheckIn("");

Download source files

Click the following link to download the code sample files: createopcclient.zip

The complete source listing

Here is the complete listing of the program.cs file

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using System.IO;
   5: using System.Xml;
   6:  
   7:  
   8: //GRAccess
   9: using ArchestrA.GRAccess;
  10:  
  11:  
  12: namespace DumpAttributes
  13: {
  14:     class Program
  15:     {
  16:         static void Main(string[] args)
  17:         {
  18:  
  19:             #region Command Line Argument Parsing
  20:  
  21:  
  22:             //("CreateOPCClient Usage:");
  23:             //("+++++++++++++++++++++");
  24:  
  25:             //("   g=<Galaxy Name>");
  26:             //("   gr=<GR Server Node>");
  27:             //("   u=<User Name>");
  28:             //("   pw=<Password>");
  29:             //("   on=<OPCClient Template Name>. Templates start with '$'!");
  30:             //("   os=<OPC Server Name>");
  31:             //("   oc=<OPC Server Computer Name>");
  32:             //("   og=<OPC Group Name>");
  33:             //("   oi1=<OPC Item Name 1>");
  34:             //("   oa1=<OPC Item Attribute Name 1>");
  35:             //("   oi2=<OPC Item Name 2>");
  36:             //("   oa2=<OPC Item Attribute Name 2>");
  37:  
  38:             //("   -> The order of the parameters doesn't matter!");
  39:             //("   -> There must be 12 parameters!");
  40:             //("   -> Use empty space characters to separate parameter=value pairs!");
  41:             //("   -> Don't use commas or semi-colon to separate parameter=value pairs!");
  42:             //("   -> The parameter=value pairs can't be longer than 254 characters!");
  43:             //("   -> The parameter specifier can't be longer than 3 characters!");
  44:  
  45:             //("   Example:");
  46:             //("   CreateOPCClient gr=localhost g=PENGUINS u=Administrator pw=ww on=$OPCClient_01 
  47:             //                     os=ArchestrA.DASABTCP.1 oc=localhost og=Group1 oi1=N100:1 
  48:             //                     oa1=Counter_1 oi2=N200:1 oa2=Counter_2");
  49:  
  50:             //Initialize dictionary
  51:             Dictionary<string, string> CmdParams = new Dictionary<string, string>(5);
  52:  
  53:             CmdParams.Add("gr", Environment.MachineName);
  54:             CmdParams.Add("g", "");
  55:             CmdParams.Add("u", "");
  56:             CmdParams.Add("pw", "");
  57:             CmdParams.Add("on", "");
  58:             CmdParams.Add("os", "");
  59:             CmdParams.Add("oc", "");
  60:             CmdParams.Add("og", "");
  61:             CmdParams.Add("oi1", "");
  62:             CmdParams.Add("oa1", "");
  63:             CmdParams.Add("oi2", "");
  64:             CmdParams.Add("oa2", "");
  65:  
  66:  
  67:             if (args.GetLength(0) != CmdParams.Count)
  68:             {
  69:                 PrintHelp();
  70:                 return;
  71:             }
  72:             else
  73:             {
  74:                 foreach (string s in args)
  75:                 {
  76:                     if (s.Length > 255)
  77:                     {
  78:                         PrintHelp();
  79:                         return;
  80:                     }
  81:  
  82:                     if (s.IndexOf('=') > 3)
  83:                     {
  84:                         PrintHelp();
  85:                         return;
  86:                     }
  87:  
  88:                     if (s.Split('=').GetLength(0) != 2)
  89:                     {
  90:                         PrintHelp();
  91:                         return;
  92:                     }
  93:                     else
  94:                     {
  95:                         try
  96:                         {
  97:                             string temp = CmdParams[(s.Split('='))[0]];
  98:                         }
  99:                         catch
 100:                         {
 101:                             PrintHelp();
 102:                             return;
 103:                         }
 104:  
 105:                         CmdParams[(s.Split('='))[0]] = ((s.Split('='))[1]);
 106:                     }
 107:                 }
 108:             }
 109:  
 110:             if (0 == String.Compare(CmdParams["gr"], "localhost", true))
 111:             {
 112:                 CmdParams["gr"] = Environment.MachineName;
 113:             }
 114:  
 115:             string GRMachineName = CmdParams["gr"];
 116:             string GalaxyName = CmdParams["g"]; ;
 117:             string UserName = CmdParams["u"]; ;
 118:             string Password = CmdParams["pw"];
 119:  
 120:             string OPCClientTemplateName = CmdParams["on"];
 121:             string OPCServerName = CmdParams["os"];
 122:             string OPCServerComputer = CmdParams["oc"];
 123:             string OPCGroupName = CmdParams["og"];
 124:  
 125:             string OPCItemName1 = CmdParams["oi1"];
 126:             string OPCItemName2 = CmdParams["oi2"];
 127:             string OPCItemAttributeName1 = CmdParams["oa1"];
 128:             string OPCItemAttributeName2 = CmdParams["oa2"];
 129:  
 130:             #endregion
 131:             #region GRAccess Login
 132:             ICommandResult CR;
 133:             IGalaxies Galaxies;
 134:             IGalaxy G;
 135:             IgObjects Objects;
 136:             ITemplate T;
 137:             ITemplate Parent;
 138:             GRAccessAppClass GR = new GRAccessAppClass();
 139:  
 140:             Galaxies = GR.QueryGalaxies(GRMachineName);
 141:  
 142:             if (Galaxies == null || GR.CommandResult.Successful == false)
 143:             {
 144:                 System.Console.Out.WriteLine(GR.CommandResult.Text + " : " + GR.CommandResult.CustomMessage);
 145:                 return;
 146:             }
 147:  
 148:             G = Galaxies[GalaxyName];
 149:  
 150:             if (G == null)
 151:             {
 152:                 System.Console.Out.WriteLine("Galaxy {0} not found on server {1}!", GalaxyName, GRMachineName);
 153:                 return;
 154:             }
 155:  
 156:             G.Login(UserName, Password);
 157:             CR = GR.CommandResult;
 158:             if (!CR.Successful)
 159:             {
 160:                 System.Console.Out.WriteLine("Login Galaxy Failed: " + CR.Text + " : " + CR.CustomMessage);
 161:                 return;
 162:             }
 163:             else
 164:             {
 165:                 System.Console.Out.WriteLine("Login Galaxy Successful!");
 166:             }
 167:  
 168:             #endregion
 169:             #region Create Derived Template from $OPCClient
 170:             string[] Names = { "$OPCClient" };
 171:  
 172:             Objects = G.QueryObjectsByName(EgObjectIsTemplateOrInstance.gObjectIsTemplate, ref Names);
 173:  
 174:             CR = G.CommandResult;
 175:             if (!CR.Successful)
 176:             {
 177:                 System.Console.Out.WriteLine("QueryObjectsByName Failed for $OPCClient Template: " +
 178:                                  CR.Text + " : " +
 179:                                  CR.CustomMessage);
 180:                 return;
 181:             }
 182:  
 183:  
 184:             T = (ITemplate)Objects[1];
 185:  
 186:  
 187:             Parent = T.CreateTemplate(OPCClientTemplateName, true);
 188:             CR = T.CommandResult;
 189:             if (!CR.Successful)
 190:             {
 191:                 System.Console.Out.WriteLine("Create Template failed for " + OPCClientTemplateName + " :" +
 192:                                  CR.Text + " : " +
 193:                                  CR.CustomMessage);
 194:             }
 195:  
 196:             #endregion
 197:             #region Configure Derived OPCClient Template
 198:  
 199:  
 200:             Parent.CheckOut();
 201:  
 202:             MxValue v = new MxValueClass();
 203:             MxValue a = new MxValueClass();
 204:  
 205:             //Configure computer name of OPCServer
 206:             v.PutString(OPCServerComputer);
 207:             Parent.Attributes["ServerNode"].SetValue(v);
 208:  
 209:             //Configure OPC server name
 210:             v.PutString(OPCServerName);
 211:             Parent.Attributes["ServerName"].SetValue(v);
 212:  
 213:             //Configure OPCGroup name
 214:             v.PutString(OPCGroupName);
 215:             Parent.Attributes["_ScanGroupAdd"].SetValue(v);
 216:  
 217:             //Add list of alias names to Group1
 218:             a.Empty();
 219:             v.PutString(OPCItemAttributeName1);
 220:             a.PutElement(1, v);
 221:  
 222:             v.PutString(OPCItemAttributeName2);
 223:             a.PutElement(2, v);
 224:  
 225:             Parent.Attributes[OPCGroupName + "._ItemAdd"].SetValue(a);
 226:  
 227:  
 228:             CR = Parent.CommandResult;
 229:             if (!CR.Successful)
 230:             {
 231:                 System.Console.Out.WriteLine("Configuring " + OPCClientTemplateName + " failed: " +
 232:                                  CR.Text + " : " +
 233:                                  CR.CustomMessage);
 234:                 Parent.CheckIn("");
 235:  
 236:             }
 237:             else
 238:             {
 239:                 Parent.Save();
 240:                 Parent.CheckIn("");
 241:  
 242:             }
 243:  
 244:             #endregion
 245:             #region Configure Derived OPCClient Item Alias Table
 246:  
 247:             v = Parent.Attributes[OPCGroupName + ".AliasDatabase"].value;
 248:             string ItemDBXMLString = v.GetString();
 249:  
 250:             //Create an XML document instance, and load XML data from AliasDatabase attribute
 251:             XmlDocument doc = new XmlDocument();
 252:             System.IO.StringReader SR = new System.IO.StringReader(ItemDBXMLString);
 253:             System.Xml.XmlTextReader TR = new System.Xml.XmlTextReader(SR);
 254:  
 255:             doc.Load(TR);
 256:  
 257:             //XPath query to the actual items
 258:             XmlNodeList nodeList = doc.SelectNodes("/ItemsList/Item");
 259:  
 260:             //Modify items list to point to the actual item names
 261:             XmlNode Item1 = nodeList[0];
 262:             Item1.Attributes["Name"].Value = OPCItemName1;
 263:  
 264:             XmlNode Item2 = nodeList[1];
 265:             Item2.Attributes["Name"].Value = OPCItemName2;
 266:  
 267:             string NewItemDBXMLString = doc.OuterXml;
 268:             Parent.CheckOut();
 269:  
 270:             v.Empty();
 271:             v.PutString(NewItemDBXMLString);
 272:             Parent.Attributes[OPCGroupName +".AliasDatabase"].SetValue(v);
 273:  
 274:             CR = Parent.CommandResult;
 275:             if (!CR.Successful)
 276:             {
 277:                 System.Console.Out.WriteLine("Setting AliasDatabase failed: " +
 278:                                  CR.Text + " : " +
 279:                                  CR.CustomMessage);
 280:                 Parent.CheckIn("");
 281:  
 282:             }
 283:             else
 284:             {
 285:                 Parent.Save();
 286:                 Parent.CheckIn("");
 287:  
 288:             }
 289:             #endregion
 290:             
 291:             System.Console.Out.WriteLine(OPCClientTemplateName + " has been successfully created and configured!");
 292:         }
 293:         #region Helper Methods
 294:         static void PrintHelp()
 295:         {
 296:             System.Console.Write("\n\n\n");
 297:             System.Console.Out.WriteLine("   g=<Galaxy Name>");
 298:             System.Console.Out.WriteLine("   gr=<GR Server Node>");
 299:             System.Console.Out.WriteLine("   u=<User Name>");
 300:             System.Console.Out.WriteLine("   pw=<Password>");
 301:             System.Console.Out.WriteLine("   on=<OPCClient Template Name>. Templates start with '$'!");
 302:             System.Console.Out.WriteLine("   os=<OPC Server Name>");
 303:             System.Console.Out.WriteLine("   oc=<OPC Server Computer Name>");
 304:             System.Console.Out.WriteLine("   og=<OPC Group Name>");
 305:             System.Console.Out.WriteLine("   oi1=<OPC Item Name 1>");
 306:             System.Console.Out.WriteLine("   oa1=<OPC Item Attribute Name 1>");
 307:             System.Console.Out.WriteLine("   oi2=<OPC Item Name 2>");
 308:             System.Console.Out.WriteLine("   oa2=<OPC Item Attribute Name 2>");
 309:  
 310:             System.Console.Write("\n\n");
 311:  
 312:             System.Console.Out.WriteLine("   -> The order of the parameters doesn't matter!");
 313:             System.Console.Out.WriteLine("   -> There must be 12 parameters!");
 314:             System.Console.Out.WriteLine("   -> Use empty space characters to separate parameter=value pairs!");
 315:             System.Console.Out.WriteLine("   -> Don't use commas or semi-colon to separate parameter=value pairs!");
 316:             System.Console.Out.WriteLine("   -> The parameter=value pairs can't be longer than 254 characters!");
 317:             System.Console.Out.WriteLine("   -> The parameter specifier can't be longer than 3 characters!");
 318:  
 319:             System.Console.Write("\n\n");
 320:             System.Console.Out.WriteLine("   Example:");
 321:             System.Console.Out.WriteLine("   CreateOPCClient gr=localhost g=PENGUINS u=Administrator pw=ww on=$OPCClient_01 os=ArchestrA.DASABTCP.1 oc=localhost og=Group1 oi1=N100:1 oa1=Counter_1 oi2=N200:1 oa2=Counter_2");
 322:         }
 323:         #endregion
 324:     }
 325: }

Compilation

To compile the program.cs file run the following command in the Visual Studio 2005 command prompt:

   1: csc /out:CreateOPCClient.exe program.cs /r:"C:\Program Files\Common Files\ArchestrA\ArchestrA.GRAccess.dll";
   2:  

Test run

To execute CreateOPCClient.exe run the following command:

   1: CreateOPCClient gr=localhost g=PENGUINS u=Administrator pw=ww on=$OPCClient_02 os=ArchestrA.DASABTCP.1 oc=localhost og=Group1 oi1=N100:1 oa1=Counter_1 oi2=N200:1 oa2=Counter_2
   2:  

Summary

The key to configure an OPCClient DIObject is the knowledge that the alias item names are stored in a single attribute as XML string. Modifying this string will create the mappings as seen in the OPCClient object's Scangroup editor.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

C# | GRAccess Toolkit | Toolkits

Related posts

Comments are closed

Powered by BlogEngine.NET 1.3.0.0
Vanilla Theme by Klaus Graefensteiner

About Klaus Graefensteiner

GRAVATAR icon of Klaus Graefensteiner I enjoy the programming of machines.

E-mail me Send mail
Blogroll as OPML OPML LinkedIn Profile View Klaus Graefensteiner's LinkedIn profile

Calendar

<<  November 2008  >>
MoTuWeThFrSaSu
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

View posts in large calendar

Recent comments

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Sign in