Navigating in Asset Hierarchies

In todays article I would like to explain how easy it is to navigate in Asset Hierarchies with method provided in the businessobject.jar file. Basically you can code all the shown stuff by using the basics you already learned about Mao’s, MboSet’s and Relationships, but why not take some easy predefined functions to do so.

For our example I will take a simple Asset Hierarchy which comes from the Maximo demo data set.

The following script will recursively output this hierarchy using the RMI technique:

import psdi.util.MXSession as MXSession
from psdi.util import MXException
 
try:
    session = MXSession.getSession()
    session.setHost('mx7mssa:13400/MAXIMO')
    session.setUserName('maxadmin')
    session.setPassword('********')
    session.connect()

except MXException, conex:
    print 'conex.getErrorGroup()     :',conex.getErrorGroup()
    print 'conex.getErrorKey()       :',conex.getErrorKey()
    print 'conex.getDetail()         :',conex.getDetail()
    print 'conex.getDisplayMessage() :',conex.getDisplayMessage()
    exit
    
def getChildrenHierarchy(asset, level):
    if asset.hasChildren():
        tab = " " * (level * 3)
        print tab + "Asset " + asset.getString("ASSETNUM") + " has childrends:"
        
        # GetChildren uses Relationship "ASSETCHILDREN"
        childrenSet = asset.getChildren()
        childrenMbo = childrenSet.moveFirst()
        while(childrenMbo != None):
            print tab + "--------------------"
            print tab + "Children Asset: " + childrenMbo.getString("ASSETNUM")
            if childrenMbo.hasParents():
                
                ownerMbo = childrenMbo.getMyParent()
                print tab + "Owner Object (Parent) for Children is " + ownerMbo.getString("ASSETNUM")
                
                parentMboSet = childrenMbo.getParents()
                parentMbo = parentMboSet.moveFirst()
                while (parentMbo != None):
                    print tab + "Parent MBO is: " + parentMbo.getString("ASSETNUM")
                    parentMbo = parentMboSet.moveNext()
                
                rootParentMbo = childrenMbo.getRootParent()
                print tab + "Root-Parent for Children is " + rootParentMbo.getString("ASSETNUM")
            # now recursivly look for more childrens...
            if childrenMbo.hasChildren():
                getChildrenHierarchy(childrenMbo, level + 1)
                
            childrenMbo = childrenSet.moveNext() 

# Main Program
if session.isConnected():
    assetSet = session.getMboSet('ASSET')
    assetSet.setWhere("ASSETNUM = '11400'")
    asset = assetSet.moveFirst()
    
    assetNum = asset.getString("ASSETNUM")
    print "Asset ", assetNum, " is the top asset in the hierarchy."
    
    getChildrenHierarchy(asset, 1)

The following table is a reference of all methods we have used in the script:

MethodDescription
assetSet = asset.getChildren()Returns a Mbo Set with all children of an asset based on the "ASSETCHILDREN" relationship
asset.hasChildren()Checks if the asset has children asset objects (returns boolean)
asset.hasParents()Checks if the asset has parent asset objects (returns boolean)
assetSet = asset.getParents()Gets a Mbo Set of all Parent asset objects based on the "PARENT" relationship.
myMbo = asset.getMyParent()Returns the Mbo of the owner Object. In our sample, a simple hierarchy, it will provide the same Mbo like the getParents() method. But the owner Mbo is more generic and could be for example a Workorder, if you navigate from a Workorder Object to an asset related to a Workorder.
topAsset = asset.getRootParent()Gets the root Mbo of the asset hierarchy.

Testing Automation Scripts with the new Maximo 7.6 “Testscript” method (Part 1: MBO based scripts)

Maximo introduced with Version 7.6 a new feature which allows you to test your automation scripts in context of a new or an existing Mbo as well as in context of the Maximo Integration Framework (MIF). The downside of that new function is, that I currently have not found any good documentation and that some features like the object path syntax are not self explaining. In this two part series I would like to introduce the new “Testscript” feature and explain how easy it is to use for your daily script testing. In part 1 we will cover the test of scripts in context of a Mbo and in part two I will show you how to test in context of the MIF.

The old styled “Run Script” testing is no longer visible but can be enabled again using the trick in my other post.

The first thing to mention if you want to test a script with the new Mbo-Test functionality is, that you need to have a script with an Object Launchpoint. Scripts with attribute launchpoints are not tested, or even worse if you have both: an object launch point and a attribute launch point on the same Mbo always the object script runs, even you select the attribute launch point script! (Might be confusing!). On the the other hand side you could utilize an Object Launchpoint testscript to set a certain attribute in a Mbo which then triggers the attribute launchpoint as well ūüėČ

Now lets create a very simple script with an object launch point for the ASSET object like the following:

print "Hello World"
print mbo.getString("ASSETNUM")

Press the “Test Script” button and you will see the following dialog:

At the top you will see information about the script and the selected Launchpoint we are running on.

With 1. you will select if we want the script to be tested against a newly created object or and existing object.

In 2. an object path can be specified if we want to reference an existing object. The format I currently found out is:

<OBJECT>[<SQL-WHERE>]

Examples could be:

ASSET[ASSETNUM='11200']
ASSET[ASSETNUM like '11%']
ASSET[ISRUNNING = 1]
ITEM[ITEMNUM='0815']

Important to remember, that you always get only a single resulting record to your script. This is the default behavior for an object script, where the resulting set is stored in the implicit Launchpoint variable mbo.

If you select Existing Object and specify an Object Path (remember to copy the Object Path to the clipboard – you have to reenter it for every test!) you can press the Test button.

You might see a result as follows:

  1. Data contains the resulting MBO in XML format.
  2. Log contains the output of the Print statements of the script.

With the Set attribute values section you can specify attributes which are overwritten from the original result. This is a nice feature when you need some testing data with certain specification (e.G. We need an asset in status of not running (ISRUNNING = 0), so we just need to specify:

So far we just have discussed the Existing Object path. If you like to create a New Object this also can be done with the testing function. The testing function basically calls an mboSet.addAtEnd() function to append a new record to the given MboSet. With the usage of Set attribute values you can predefine fields of the newly created Mbo before it is handed over to the Jython script.

A bit strange is, that if you try to create an Asset Object and do not specify an ASSETNUM you will get an error, that the asset field needs to be specified. If you will set the ASSETNUM field you will get an error, that it is readonly and cannot be set.

The only solution I found so far is to hardly overwrite the readonly check by using the¬†Field Flag “NOACCESSCHECK”:

from psdi.mbo import MboConstants
mbo.setValue("ASSETNUM", "ASS0815", MboConstants.NOACCESSCHECK )
mbo.setValue("DESCRIPTION", "New Test Asset!")

So far for this first tutorial on the new Test script capability. In the next part I will cover the capability to test automation scripts customizing the MIF Interface.