How to use Dynamic attributes to expose ConfigOnly attribute values in runtime

by Klaus Graefensteiner 5/13/2008 5:32:59 AM

Introduction

The building blocks of the Industrial Application Server are Application Objects. These objects themselves are made out of components called Primitives. Primitives have Attributes and Attributes have Properties. Each Application Object has at least the Common Primitive that is shared amongst all objects. In addition to this Primitive Application Objects can contain several other Primitives that are provided by the Industrial Application Server. On top of the basic set of Primitives one or more Custom Primitives can be added to an Application Objects. The Application Object Toolkit provides the tools to create Custom Primitives and glue them together with other standard Primitives to create a new type of Application Object.

Components of the International Spacestation

Figure 1: Components of the International Spacestation

The AOT allows a developer to statically define Attributes of a new Custom Primitive in the Object Designer, or to dynamically create Attributes in the PackageServer component of the new Application Object. This post explains how to create Dynamic Attributes to expose other Attributes that are for example only available during configuration to the runtime sub system.

Prerequisites

The sample Application Object discussed in this post has been developed using the following tools:

  • Visual Studio.NET 2003
  • IAS 3.0 SP1
  • Application Object Toolkit 1.0

Problem description

Some Attributes values are only available during the configuration of the object and are not accessible at runtime. The Attributes "MinorVersion" and "CodeBase", which are part of the Common Primitive, are configuration only Attributes. The following sample describes a simple approach to exposing these values to the runtime sub system by creating new Dynamic Attributes that are visble in runtime and copying the values of the configuration Attributes into the new Dynamic attributes

MinorVersion and CodeBase Attributes are ConfigOnly 

Figure 2: MinorVersion and CodeBase Attributes are ConfigOnly

Solution

Create new AOT project

Open the AOT Object Designer and create a new object called "ExportPackageOnlyAttributes". Then add one static Attribute in the Designer of type integer with the name "PV". Assign it the category "Writeable_USC_Lockable"

Creating new object with the ObjectDesigner

Figure 3: Creating a new object with the Object Designer

Now generate the source code, open the Visual Studio solution and build the new Application Object. Import it into the IDE and deploy it to an Application Engine.

Modify the Package Server

From this point on all modifications are made to the "ExportPackageOnlyAttributesPackage.cpp" file of the Package Server Visual Studio project. The code that we are going to add will be executed by the "CExportPackageOnlyAttributesPackage::OnPostCreate" event handler.

Add Attribute

To add a new attribute we need access to two functions that are provided by the Site COM object, which we get by calling the GetSite() function. First we want to make sure that the Attribute hasn't already been added by checking "GetAttributeHandle" passing in the name of our Dynamic Attribute. If it returns a valid handle, then we know that the Attribute has already been added, if not we are going to add the Attribute.

   1: // Create two dynamic attributes if they don't exist already
   2: // First check whether they exist
   3:  
   4: ATL::CComBSTR MinorVersionExName = L"MinorVersionEx";
   5: ATL::CComBSTR MajorVersionExName = L"MajorVersionEx";
   6: AttributeHandle MinorVersionExAttributeID;
   7: AttributeHandle MajorVersionExAttributeID;
   8:  
   9:  
  10: IPrimitivePackageSite * P = GetSite();
  11:  
  12: // 1) MINOR VERSION
  13: HRESULT    r = P->GetAttributeHandle( MinorVersionExName, &MinorVersionExAttributeID);
  14:  
  15: if(!(SUCCEEDED(r)))
  16: {
  17:     LogWarning(L"GetAttributeHandle - HRESULT = %x", r);
  18:     return;
  19: }
  20:  
  21: LogInfo(L"%s has AttributeID = %d" , MinorVersionExName, MinorVersionExAttributeID.shAttributeId);
  22:  
  23: // If Attribute doesn't exist, create one
  24: if( MinorVersionExAttributeID.shAttributeId == 0)
  25: {
  26:  
  27:     AttributeInfo ai;
  28:     AttributeID ID;
  29:  
  30:     ai.Name = MinorVersionExName;
  31:     ai.Category = MxCategoryWriteable_C_Lockable; 
  32:     ai.Security = MxSecurityFreeAccess;
  33:     ai.Datatype = MxInteger;
  34:     ai.LockType = MxLockedInMe;
  35:  
  36:     //Add dynamic attribute
  37:     r = P->AddAttribute(eTopLevelCustomPrimitiveId, &ai, &ID);
  38:  
  39:     if(!(SUCCEEDED(r)))
  40:     {
  41:         LogWarning(L"AddAttribute - HRESULT = %x", r);
  42:         return;
  43:     }
  44:  
  45:     LogInfo(L"Added Attribute %s! Its AttributeID = %d" , MinorVersionExName, MinorVersionExAttributeID.shAttributeId);

The category of the two Dynamic Attributes is set "Writeable_C_Locable". This way the Attribute values are constants and cannot be changed in runtime.

Set Value

Once we created the new Dynamic Attributes we can get the values from the "MinorVersion" and "CodeBase" and copy them to the new Dynamic Attributes "MinorVersionEx" and "MajorVersionEx". For the latter one we have to parse the "CodeBase" Attribute value string and get the version number at the end of the string. Here is the source code that does it.

   1: // Set value of dynamic attribute equal to PackageOnly MajorVersion attribute
   2: CMxValue MxCodeBase = Get(idxCommonCodeBase, eCommonPrimitiveId);
   3: long int MajorVersion = 0;
   4: ATL::CComBSTR CodeBase = L"";
   5:  
   6: // Getting CodeBase attribute from Common Primitive
   7: r = MxCodeBase->GetString(&CodeBase);
   8: if(!(SUCCEEDED(r)))
   9: {
  10:     LogWarning(L"GetString - HRESULT = %x", r);
  11:     return;
  12: }
  13: LogInfo(L"CodeBase is: %s", CodeBase);
  14:  
  15: // Converting BSTR to STL wstring
  16: std::wstring strCodeBase(CodeBase);
  17:  
  18: // Parsing version number from ProgID string contained in CodeBase attribute
  19: size_t b = strCodeBase.find_last_of(L".");
  20: LogInfo(L"b %d", (int) b);
  21: std::wstring strMajorVersion = L"";
  22: strMajorVersion = strCodeBase.substr(b + 1);
  23:  
  24: // Converting string to long integer
  25: swscanf(strMajorVersion.c_str(), L"%d", &MajorVersion);
  26:  
  27: LogInfo(L"MajorVersion String: %s", strMajorVersion.c_str());
  28: LogInfo(L"MajorVersion Integer: %d", MajorVersion);
  29:  
  30: // Converting long integer to MxValue object
  31: CMxValue MxMajorVersion(MajorVersion);
  32:  
  33: // Setting MajorVersionEx attribute value
  34: Set(ID, MxMajorVersion);

Build and test

Compile the modified project, import the new object and deploy it. The new dynamic attributes should now display the values of the configuration counter parts. Check the object property page in the IDE and the runtime values of object attributes in the ObjectViewer.

Object properties displayed by the IDE

Figure 4: Object properties displayed by the IDE

ObjectViewer displays the new dynamic attributes

Figure 5: ObjectViewer displays the new Dynamic Attributes

Download

The complete Visual Studio .NET 2003 solution can be downloaded here: CExportPackageOnlyAttributes.zip

Summary

Creating Dynamic Attributes is without any doubt an advanced feature of the Application Object toolkit. On the other hand Dynamic Attributes can increase productivity of an application developer by providing a mechanism to automate the "shaping" of an Application Object.

Be the first to rate this post

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

Tags: , ,

ArchestrA Object Toolkit | Toolkits | Wonderware

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

<<  September 2008  >>
MoTuWeThFrSaSu
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

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