Maximo Application Suite

MAS – Techno‑Functional

Search This Blog

Friday, February 9, 2024

MAXIMO : Don't Let Your Assets Sleepwalk: Wake Up with Twilio SMS Notifications in Maximo 7.6.1.3

Imagine this: a critical piece of equipment goes down in the dead of night. You rely on email notifications, but your technicians rarely check their inboxes after hours. The delay in response costs your company precious time and productivity. Ugh!

This scenario is all too common, but fear not! Timely communication is key to effective asset management, and Twilio's SMS integration with IBM Maximo 7.6.1.3 can be your knight in shining armor.

Picture this: an alert pops up on your tech's phone, instantly notifying them of the issue. They spring into action, resolving the problem before it snowballs. Equipment humming happily? Check. Happy boss? Double check!

So, how do you make this SMS dream a reality? Don't worry, we've got you covered. This sample use case will walk you through the process, step-by-step, like a friendly Maximo whisperer. And you can easily plug-in into your unique situations with little to no much changes.

Ready to get started? Buckle up!

1. Twilio Time: Your Gateway to Speedy Alerts:

Think of Twilio as your communication hub. Sign up for their free trial (plenty of credits for testing!), and grab your Account SID and Auth Token – these are your magic keys. We'll use them later.

2. Sigoptions & Actions: Speak Maximo's Language:

In Maximo-land, sigoptions control what actions you can take. We'll create a new one called "sendsms" and link it to the "sendsms" action in the Asset application as sample use case here. It's like teaching Maximo a new trick!

3. Scripting Magic: Your SMS Superpower:

Now for the cool part – the automation script. This code, triggered whenever you select "sendsms," uses Twilio's API to send those life-saving SMS alerts. Don't worry, we'll provide the code and explain what each part does.   

import java.net.HttpURLConnection as HttpURLConnection import java.net.URL as URL import java.io.OutputStreamWriter as OutputStreamWriter import java.io.BufferedReader as BufferedReader import java.io.InputStreamReader as InputStreamReader import java.util.Base64 as Base64 # Twilio account credentials account_sid = 'account_Id' auth_token = 'auth_token' twilio_number = '+13512008888' # Function to send SMS using Twilio def send_sms(to_number, message): url = 'https://api.twilio.com/2010-04-01/Accounts/' + account_sid + '/Messages.json' data = { 'To': to_number, 'From': twilio_number, 'Body': message } data_str = '&'.join(["{}={}".format(key, value) for key, value in data.items()]) url_obj = URL(url) connection = url_obj.openConnection() connection.setRequestMethod("POST") connection.setDoOutput(True) auth_str = account_sid + ":" + auth_token encoded_auth_str = Base64.getEncoder().encodeToString(auth_str.encode()) connection.setRequestProperty("Authorization", "Basic " + encoded_auth_str) connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") writer = OutputStreamWriter(connection.getOutputStream()) writer.write(data_str) writer.flush() response_code = connection.getResponseCode() reader = BufferedReader(InputStreamReader(connection.getInputStream())) response = "" line = reader.readLine() while line is not None: response += line line = reader.readLine() reader.close() return response_code, response # Example usage to_number = '+1788xx5011' # Receiver's phone number message = 'Hello from IBM Maximo ! via Twilio SMS Gateway' status_code, response = send_sms(to_number, message) print('SMS sent with status code:', status_code) print('Response:', response)

4. Testing, Testing, 1, 2, 3:

Ready to see your handiwork in action? Open Maximo, choose an asset, and hit "sendsms." Did your phone buzz with a notification? If so, you're golden! Check the Twilio console for confirmation. High five! Here it is in actions :

In Assets new action to send sms :


And now once clicking it , it sends this template sms to mentioned number as of now hard coded in our automation script for this explanation purpose as below                         

5. Beyond the Basics: Level Up Your SMS Game:

Want to customize the message content or trigger notifications based on specific events? We've got tips for that too! Plus, we'll mention some potential roadblocks and how to navigate them smoothly.

Remember, integrating Twilio with Maximo isn't just about fancy tech; it's about empowering your team to respond quickly and efficiently, ultimately saving you time, money, and maybe even your sanity!

Ready to wake up your asset management with the power of SMS? Dive into the full similar use cases following the detailed instructions in this post and share insights for community.

P.S. Don't forget to share your SMS notification success stories in the comments!

Tuesday, August 29, 2023

MAXIMO : Email Listener using OAUTH using GMAIL account - 7.6.1.2 /3

 Here I am going to provide details steps for how to configure email listener using GMAIL with OAUTH authentication.


Pre-requisite you should have SMTP configurations set up and emails in Maximo are already working.

You may refer IBM documentation for this - Configuring SMTP.

So once SMTP is properly set up and email sending through Maximo applications works fine , we will need to move to prepare and get OAUTH parameters like Refresh Token , Client ID , Client Secret etc. for email address being used for email listener with OAUTH protocol.

Here I will cover steps for getting these details for Gmail account.

First step is to have email account  : Create a new Gmail account   / you may use your existing Gmail account.

Next steps is work with Google Cloud API to configure and generate/ get required parameters like Client ID , Client Secret and Refresh token for above Gmail account using cloud API library services.

Broadly this can be done using following steps :

1. Set up project using Google cloud dashboard logging in with your Gmail account.

2. Next enable GMAIL API under your project

    


3. Once API is enabled , credentials need to be created for connecting to account via GMAIL API

            

    




After hitting Save and continue , you should provide scope for API access /authorization
         


Now you should be able to download details in JSON format or can copy it from google cloud dashboard like Client ID , Client Secret.

    


Now next step is to get refresh token for this Email configuration/ client ID using postman client :
To get refresh token first we need to get code to establish session with api

URL :   Hit URL from browser in below format and within browser while redirecting it will generate CODE
        

It should ask you to login using your email account 
    

Then you have to click "continue" couple times and it will redirect to your maximo login page / redirect URI provided during credentials creation.
After successful login , you can try putting same above URL again and proceed is similar manner as session was already established this time it will automatically login maximo and URL
will now have auth code 





Postman POST request should be done to get refresh token :
URL :  https://oauth2.googleapis.com/token?
Parameters - client_id , client_secret ( values received in above steps)
redirect_uri : - your maximo url e.g. https://host:port/maximo ( which is used as redirect URL during credentials
creation )
grant_type : authorization_code
     prompt = consent
access_type = offline





This request should give you refresh time on first iteration.

Once you get refresh token you should be able to configure Email Listener within Maximo.





This will now complete Email Listener configuration using OAUTH.

I will continue and update this post for additional configurations like Email Interaction and sample PO workflow where PO status will be changed via email response being listened and processed by email listener.


Friday, August 4, 2023

MAXIMO : MIF Integration Changing status with inbound processing

 

How do we have change status functionality get triggered and record status history when sending inbound transaction with new status than the current one on record ?


Status change is an operation that is performed on stateful Maximo Business Objects. For example, a Person object can be changed from ACTIVE to INACTIVE and back by means of a button or menu selection in the application screen.

In order to perform a status change with an inbound Integration Framework transaction, you must include the STATUSIFACE and NP_STATUSMEMO attributes in addition to the STATUS attribute with the new value, and use the StatefulMicSetIn processing class. (Integrations that are provided with Maximo already use this class or have an integration-specific processing class which is an extension of StatefulMicSetIn.)

Note that the STATUS and STATUSDATE fields should be restricted in the object structure. Verify this in the Inbound Setting Restrictions in the Object Structures application.

STATUSIFACE is a boolean attribute which specifies how the transaction should be processed with regards to status changes:

STATUSIFACE=0 - This transaction will perform the specified Action (Add or Replace for example) on the data, save it, and then, if the new status is different from the existing status, perform a status change operation. Note that an invalid status change, such as attempting to cancel a closed workorder, will cause an error.

STATUSIFACE=1 - This transaction is ONLY a status change. Any data other than the key attributes which identify the record are ignored. If the new status is different than the existing status, perform a status change operation.

STATUSIFACE not present or has a null value : not present or null value are treated as STATUSIFACE=0.

The NP_STATUSMEMO attribute is used for the memo or remark which accompanies the status change. For example, if changing a workorder status, the value of NP_STATUSMEMO will be placed in the MEMO field of the WOSTATUS record that is inserted by the status change.

If you create a custom Object Structure for a stateful Maximo object, you must also add STATUSIFACE (and NP_STATUSMEMO if the status has a remarks or memo component in the status change dialog on the screen) to the Object Structure by adding it as a nonpersistent attribute to the main object in Database configuration. 

You must also specify psdi.iface.mic.StatefulMicSetIn as the processing class in the object structure definition. If you are creating a custom processing class, then it must extend the StatefulMicSetIn class.

Usage

In most cases you will only need to specify a STATUSIFACE of 0. This will ensure that the integration action is carried out and that the status will be changed if the new status is different.

If you plan on sending in transactions that will only change a status, such as approving a workorder or deactivating a person, then you can use the same integration that you use for data updates with status changes, but set STATUSIFACE to 1 and only send the key attribute values which identify the record, such as WONUM and SITEID for a workorder, along with the new status value.

Reference : IBM Technote MIF Changing status with an inbound transaction

Thursday, June 22, 2023

MAXIMO : Reset user password from backend

There are sometimes situations like lower environments like DEV , TEST ,TRAINING etc. gets refreshed from Production and all users get inactivated , password reset to default values and in some situations default values gets changes without notice and you had to wait for onshore counter part to be available to share details .


This can be dealt with updating you user's password from backend , generally developers have such access in development environments.

Below are details how to do this in different flavors of databases : 

First of all, get the encrypted password string of maxadmin user, where  for e.g. password is 'maxadmin'

SQL> Select userid, password from maxuser where userid = 'MAXADMIN'


output :
USERID PASSWORD
--------- --------------------------------
MAXADMIN x'10FE6F4650B2ACB49A2121D7E6133E64'

Now update user's password with this string, so that the password would be same like maxadmin's password

Oracle:
UPDATE maxuser
SET PASSWORD = '10fe6f4650b2acb49a2121d7e6133e64'    --
WHERE userid = 'XXXX' --user

SQL Server:
UPDATE maxuser
SET PASSWORD = 0x10fe6f4650b2acb49a2121d7e6133e64    --0x
WHERE userid = 'XXXXX' --user

DB2:
UPDATE maxuser
SET PASSWORD =x'10fe6f4650b2acb49a2121d7e6133e64'    --x''
WHERE userid = 'XXXX' --user


Reference: http://www-01.ibm.com/support/docview.wss?uid=swg21645570

Monday, June 19, 2023

MAXIMO : Automation Script to invoke external URL without Publish Channel or Invocation Channel

Maximo integration capabilities like Publish Channels , Invocation Channels provide way for invoking external service via HTTP calls.


But there are sometimes needs where external API needs to be triggered during processing logic within user interaction and continuation of user activity through API call return/processing.

Get Data from External API Call:

So we can use ScriptService class and its method httpgetasjson to get the data from external API call and then continue maximo operation using the data requested from external api by user's activity.

 service.httpgetasjson(<url>, <userid>, <headers>, <password>)

Here we can call API "URL" and pass connection and header parameters.


Here is sample code snippet :

from com.ibm.json.java import JSONObject, JSONArray

# Invoking an URL

url = "https://www.external-api.com/" userid = api-user passwd = api-pwd # Invoke URL response = service.httpgetasjson(url, userid, None, passwd) status = response.getStatusLine().getStatusCode() obj = JSONArray.parse(response.getEntity().getContent()) if status == 200: # OK else: # error


Push Data to External API :

So we can use ScriptService class and its method httppostasjson to post the 

data from maximo to external API call.

service.httppostasjson(<url>,<userid>,<password>, <headers>, <json>)

Here is sample code snippet

from com.ibm.json.java import JSONObject, JSONArray

# create a JSON object jsonObject = JSONObject() jsonObject.put("equipment", mbo.getString("ASSETNUM")) jsonObject.put("description", mbo.getString("DESCRIPTION")) # Invoking an URL url = "https://www.external-api.com/" userid = api-user passwd = api-pwd # Invoke URL response = service.httppostasjson(url, userid, passwd, None, jsonObject) status = response.getStatusLine().getStatusCode() obj = JSONArray.parse(response.getEntity().getContent()) if status == 200: # OK else: # error