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

    session = MXSession.getSession()

except MXException, conex:
    print 'conex.getErrorGroup()     :',conex.getErrorGroup()
    print 'conex.getErrorKey()       :',conex.getErrorKey()
    print 'conex.getDetail()         :',conex.getDetail()
    print 'conex.getDisplayMessage() :',conex.getDisplayMessage()

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:

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.

The UserInfo Object

In this Blog I would like to introduce the often used UserInfo Object in Maximo / ICD Scripting. There are a number of API method calls which require a UserInfo object as a parameter and therefore you need to know how you can get a reference to that object. In the second part of this Blog I will show you some method calls on utilizing the UserInfo yourself.

Get a reference to the UserInfo Object

When you run a Jython script there are several ways to get the UserInfo object.

Get the userInfo for the actual user the script is running in context of a Mbo

userInfo = mbo.getUserInfo()  # @UndefinedVariable

Get the userInfo for a specific user

from psdi.server import MXServer
mxServer = MXServer.getMXServer()
userInfo = mxServer.getUserInfo("maxadmin")

Get the userInfo for the System user (MAXADMIN)

from psdi.server import MXServer
mxServer = MXServer.getMXServer()
userInfo = mxServer.getSystemUserInfo()

Get a new userInfo from Migration Services (MAXINTADM)

from psdi.server import MXServer
from psdi.iface.mic import MicService

mxServer = MXServer.getMXServer()
micService = MicService(mxServer)
userInfo = micService.getNewUserInfo()

Usage of the UserInfo Object

Beside the fact that a lot of method calls of Maximo/ICD API’s require a valid UserInfo object it has a number of interesting Getter and Setter functions which might help in your script. I would like to show you only a small subset of these methods here in this Blog. A full list can be found in the JavaDoc documentation.

Here I have a small demonstration script for you which can be directly run from the Automation Scripts application (look here how to do this):

#DESCRIPTION:Example script showing capabilities of the UserInfo Object

from psdi.server import MXServer

mxServer = MXServer.getMXServer()
userInfo = mxServer.getSystemUserInfo()

print "User Name        : " + str(userInfo.getUserName())
print "User Display Name: " + str(userInfo.getDisplayName())
print "User ID          : " + str(userInfo.getLoginUserName())
print "e-Mail           : " + str(userInfo.getEmail())
print "Default Language : " + str(userInfo.getDefaultLang())
print "Current Language : " + str(userInfo.getLangCode())
print "Timezone         : " + str(userInfo.getTimeZone())

# Check if we are running in Interactive mode or from a System Job
if not userInfo.isInteractive():
    print "------"
    print "Setting Language code to EN"
    print "------"


    print "Current Language : " + str(userInfo.getLangCode())

The script basically will get the UserInfo Object for the System User and after that will print out a couple of information. To avoid Null Pointers I have convert all outputs to a String value. At the end it will change the current Language for the user to a different value.

User Name        : MAXADMIN
User Display Name: Max Admin
User ID          : MAXADMIN
e-Mail           : None
Default Language : DE
Current Language : DE
Timezone         : sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
Setting Language code to EN
Current Language : EN

Some obstacles in the output:

  1. The Timezone value is not a string, but another object of type sun.util.calendar.ZoneInfo. If you need that information you should access the value with the methods from the ZoneInfo object.
  2. I implemented a condition “userinfo.isInteractive()”. Interactive normally means, that a script runs based on an end user GUI Action, while “not interactive” means that the script runs from an escalation or automatic workflow. If we run the script manually from the Automation Script application the isInteractive() method returns false.