Maximo

Maximo

Come for answers, stay for best practices. All we're missing is you.

 View Only
  • 1.  Automating Work Order Creation in IBM Maximo Application Suite with Python: Towards Intelligent Maintenance

    Posted 10/13/25 11:32 AM

    Automating Work Order Creation in IBM Maximo Application Suite with Python: Towards Intelligent Maintenance


    🔹 Introduction

    Automation is reshaping maintenance management. By leveraging Python scripting within IBM Maximo Application Suite (MAS), organizations can automatically create and manage work orders - improving efficiency, accuracy, and responsiveness.
    Let's explore how a few lines of Python can transform the way maintenance teams operate.


    🔹 Technical Context

    Since MAS 8 and 9, IBM Maximo includes a flexible scripting environment based on Python (Jython).
    This enables developers and administrators to automate actions directly within Maximo, such as:

    • Automatically generating work orders when an anomaly is detected

    • Creating WO based on asset performance thresholds

    • Integrating external data (IoT, APIs, AI) to trigger maintenance tasks


    🔹 Example: Automatically Creating a Work Order

    from psdi.server import MXServer from psdi.mbo import MboRemote # Connect to the Maximo server mxServer = MXServer.getMXServer() # Access system user info userInfo = mxServer.getSystemUserInfo() # Create a new Work Order set woSet = mxServer.getMboSet("WORKORDER", userInfo) # Add a new Work Order newWO = woSet.add() newWO.setValue("DESCRIPTION", "High temperature alert detected on pump P-1001") newWO.setValue("ASSETNUM", "P-1001") newWO.setValue("WOPRIORITY", 1) newWO.setValue("WORKTYPE", "CM") # Corrective Maintenance newWO.setValue("SITEID", "MAINPLANT") # Save the record woSet.save() print("✅ Work Order successfully created automatically!")

    🔹 Code Explanation

    • MXServer.getMXServer() → Connects to the Maximo server

    • getMboSet("WORKORDER") → Creates a manipulable set of work orders

    • add() → Adds a new record

    • setValue() → Defines core fields (description, priority, site, etc.)

    • save() → Commits the record to the Maximo database

    This script can be triggered through an Automation Script Launch Point, such as:

    • Object Launch Point – when an asset changes status

    • Cron Task Launch Point – for scheduled automation


    🔹 Key Benefits

    ✅ Reduced manual processing time
    ✅ Improved reliability and maintenance responsiveness
    ✅ Seamless integration with IoT and AI data (e.g., Maximo Monitor or Visual Inspection)
    ✅ Fully customizable automation without altering Maximo's core logic


    🔹 Conclusion

    Python automation within IBM MAS offers a powerful way to make maintenance smarter and more proactive.
    For organizations seeking to optimize operational performance, Jython scripting is a gateway to intelligent, data-driven maintenance.

    alt

    #IBMMAS #Maximo #MaximoApplicationSuite #PythonAutomation #AIMaintenance #IBMChampion #DigitalTransformation #EnterpriseAssetManagement #Jython #Automation #PredictiveMaintenance #IBMCommunity #Maintenance4_0



    ------------------------------
    Yasmine Ghomri
    IBM Maximo / MAS 9 Expert | Technical Lead | IBM Digital Badges
    SINORFI
    ------------------------------


  • 2.  RE: Automating Work Order Creation in IBM Maximo Application Suite with Python: Towards Intelligent Maintenance

    Posted 10/17/25 10:00 AM
    Your Script is very well explained.
    The improved script below enhances your original version by adding structured logging using MXLoggerFactory, proper error handling with try/except/finally blocks, automatic cleanup of the MboSet to prevent memory leaks.
    It also includes automatic population of the work order's location based on the associated asset, detailed success and error messages printed to both the console and Maximo logs
     
    from psdi.server import MXServer
    from psdi.util.logging import MXLoggerFactory
    from java.lang import System
     
    logger = MXLoggerFactory.getLogger("maximo.script.auto_create_workorder")
     
    woSet = None
     
    try:
        # Connect to the Maximo server
        mxServer = MXServer.getMXServer()
        userInfo = mxServer.getSystemUserInfo()
        logger.info("Connected to MXServer using system user info")
     
        # Create a new Work Order set
        woSet = mxServer.getMboSet("WORKORDER", userInfo)
        newWO = woSet.add()
     
        # Set field values
        newWO.setValue("DESCRIPTION", "High temperature alert detected on pump P-1001")
        newWO.setValue("ASSETNUM", "P-1001")
        newWO.setValue("WOPRIORITY", 1)
        newWO.setValue("WORKTYPE", "CM")  # Corrective Maintenance
        newWO.setValue("SITEID", "MAINPLANT")
     
        # Optional: Auto-populate location from Asset
        assetMbo = newWO.getMboSet("ASSET").getMbo(0)
        if assetMbo and not assetMbo.isNull("LOCATION"):
            newWO.setValue("LOCATION", assetMbo.getString("LOCATION"))
            logger.info("LOCATION auto-populated from asset")
     
        # Save the Work Order
        woSet.save()
        wonum = newWO.getString("WONUM")
     
    except Exception, e:
        logger.error("Error creating Work Order")
     
    finally:
        if woSet is not None:
            woSet.close()
            logger.info("MboSet closed properly")



    ------------------------------
    Selvaraj Subramani
    Maximo Consultant
    Sedin Technologies
    ------------------------------



  • 3.  RE: Automating Work Order Creation in IBM Maximo Application Suite with Python: Towards Intelligent Maintenance

    Posted 10/20/25 11:21 PM

    Selvaraj, that's a nice touch putting on some logs and error handling.

    I'd go further and replace the MXLoggerFactory with the built in implicit service variable to log the messages. By using the service.log_error(), service.log_debug() and service.log_info() functions, you can change the log level in the AutomationScript to print the log messages in the logs rather than changing it in the Logging Application, which would impact the entire application logging level.

    Cheers,

    Maycon



    ------------------------------
    If this post helps, please consider accepting it as a solution to help other members find it more quickly.

    Maycon Belfort
    Cloud and Infrastructure Engineer
    Naviam
    Melbourne
    ------------------------------



  • 4.  RE: Automating Work Order Creation in IBM Maximo Application Suite with Python: Towards Intelligent Maintenance

    Posted 10/21/25 09:33 AM

    In the sample code, calling `service.log_debug()` and etc sounds fine, because the strings are flat. However, I generally have 2 problems with calling `service.log_debug()` and etc:

    One problem with calling `service.log_debug()` and etc is that the string to be logged will always be assembled before being sent to the method, and the method may then ultimately decide to not log the string due to the log level being less verbose. Rephrased, calling `service.log_debug()` comes with a guaranteed performance penalty when the string is not flat. Fo example, after the `woSet.save()`, if we called `service.log_info("Created work order: {}".format(newWO.getString("WONUM")))`, the work to `getString("WONUM")` would happen and to merge the returned value into the format string would be guaranteed to happen, even if the Log Level on the script was set to WARN or ERROR (meaning the computed string would not be logged).

    The second problem particularly with calling `service.log_debug()`, as opposed to calling `service.log_info()` or higher, is that setting the logging for the script to DEBUG ends up logging every read of every variable -- details I would expect at the TRACE level that Maximo does not support. This means that in order to see what was sent to `log_debug()` you have to overflow your logs with trace details that you want to not see in order to see your debug messages.



    ------------------------------
    Blessings,
    Jason Uppenborn
    Sr. Technical Maximo Consultant
    Cohesive
    ------------------------------



  • 5.  RE: Automating Work Order Creation in IBM Maximo Application Suite with Python: Towards Intelligent Maintenance

    Posted 10/21/25 10:59 AM

    A few points:

    1) The performance penalty for string concatenation is usually in the single digit milliseconds that when taken in context that we are talking about an automation script, itself is ridiculously inefficient by comparison, is silly. If you actually cared about performance as a priority you wouldn't be writing automation scripts in the first place. There is a lot to be said for clarity over notional performance gains. 

    2) The implementation of service.log_[level]() is pretty messy. Calling service.log() with no level modifier is the only time that the log level on the actual script is considered and it logs at either info or debug, ignoring everything else.  The rest of the service.log_[level] calls are just using the maximo.script.[script name] standard Maximo logger and this must be configured in the standard Logging application.

    In general I avoid using the service.log methods because the service implicit variable is not available in all contexts and its implementation of logging is generally. The original suggestion of:

    MXLoggerFactory.getLogger("maximo.script.auto_create_workorder") 

    is a good suggestion and provides the most clarity and control.  The only thing to note is that in MAS 9.1 there is now validation that requires any logger created under the maximo.script parent logger to exists as a script name. So in this example there would have to be a script named auto_create_workorder otherwise creating the logger entry in the Logging application for this specific script would fail.  For this reason you may consider creating a new parent logger and putting your scripts under that instead, which also addresses Jason Uppenborn's compliant about unintentional log messages.

    3) Unrelated to the logging discussion, the original suggestion has this:

        # Connect to the Maximo server
        mxServer = MXServer.getMXServer()
        userInfo = mxServer.getSystemUserInfo()
        logger.info("Connected to MXServer using system user info"

    A couple of points, when you call MXServer.getMXServer() you are not "connecting" to the Maximo server, you are getting a static singleton reference to the MXServer object. Connecting suggests that there is a network call, which is not the case.

    Second and more importantly, avoid using the getSystemUserInfo() call because any resources fetched using this user that are not properly closed will never get cleaned up as this the system user is never logged out.  Furthermore, the system user has full system privileges so whatever actions you are taking will have elevated privileges from the standard user.  You should use the implicit userInfo variable if available or the getUserInfo() method from the implicit mbo variable if available.



    ------------------------------
    Jason VenHuizen
    Naviam
    https://naviam.io
    https://opqo.io
    ------------------------------