I’ve had a lot of conversations recently with folks attempting to implement more Condition Monitoring within their organization. The benefits of shifting from time-based maintenance to condition- or use-based maintenance are well documented and very real. However, making that shift involves a fair amount of planning, analysis, and technology. This article will show an example of how to bridge a small portion of the technology gap; specifically we will focus on creating meter readings in Maximo via the JSON API available in Maximo 7.6.0.2 and higher.
Meter readings are the heart of how Condition Monitoring is implemented in Maximo. They represent a piece of data at a point in time associated with an asset. This data could be related to the asset’s condition such as temperature, pressure, voltage, etc. This data could also be related to the asset’s usage such as an odometer reading, the number of cycles of the asset, etc. Lastly, the data could be based on a simple value list such as Pass/Fail, Open/Closed, Blowing / Not Blowing, etc.
To create a new meter reading via Maximo’s JSON API, let’s start with an example:
Let’s look at this part-by-part. First, we start with the HTTP POST itself.
POST /maximo/oslc/os/mxasset/_QkVERk9SRC8xMTQ1MA==
This message needs to be an HTTP POST (not HTTP GET). The http://mxapprove.a3jgroup.com/maximo portion of the URL is your Maximo environment’s URL. Substitute that for your own environment’s URL. The /oslc part of the path represents the usage Maximo JSON API. The /os part of the path tells the API that the next part of the path (in our example is /mxasset) will be an Object Structure in Maximo. Finally, the /_QkVERk9SRC8xMTQ1MA== represents a unique identifier for an Asset record that can be referenced in the MXASSET Object Structure. This identifier can be found be querying for the asset using an HTTP GET to the same MXASSET Object Structure, or it can be derived by base64 encoding the asset’s SITEID + “/” + ASSETNUM and prefixing that string with an underscore (“_”) character.
Next are the various headers.
maxauth: c21pdGg6c21pdGgx
Content-Type: application/json
properties: *
x-method-override: PATCH
patchtype: MERGE
The maxauth header represents the credentials that are being used to broker the transaction. The value is a base64 encoded string of the format USERNAME + “:” PASSWORD. In an LDAP environment, switch the maxauth header to Authorization and prefix the string “Basic ” to the base64 encoded value. The Content-Type header tells the HTTP request that the body of the message will be in JSON format. The properties header tells the request which fields from the MXASSET Object Structure should be sent back in the HTTP response, with the * character representing all fields in the object structure. The x-method-override header with a value of PATCH tells Maximo that this will be an update to the asset record, and the patchtype header with a value of MERGE tells Maximo to add a new record while keeping the other ASSETMETER records. Without that header, the integration will replace all of the ASSETMETER records with the list in the message.
Note that we don’t need any identifying information about the asset in the message body, such as the ASSETNUM or SITEID. This is because we are required to specify the unique identifier in the URL string. We specify the assetmeter key as an array of meters associated with the asset. For this example, we are only updating a single meter against the asset (Outlet Pressure). In our object, we specify the Meter Name and New Reading value. The linearassetmeterid key with a value of 0 is necessary due to that field being part of the unique identifier on the ASSETMETER table. Values such as the New Reading Date and Inspector will default based on the current date and the logged in user credentials, but can also be specified explicitly in the message.
Please feel free to leave questions or comments below. Good luck in your IoT journey!
Alex Walter is the Chief Innovation Officer at the A3J Group, a company he formed to address the need for innovative software solutions and integrated consulting services within the EAM industry. Alex brings 17 plus years of experience in business consulting in various industries including Life Sciences, Oil and Gas, Water and Waste Management, Education, Government Facilities, among others.
Alex lives in Tampa, FL with his wife, two sons, and dogs. In his free time, he enjoys running half marathons, making space in his garage for new camping and outdoor equipment, traveling to far off places with the Walter Circus, and remaining hopeful that his NY Jets' best days are ahead of them and not behind.
8 Thoughts on “Maximo JSON API: An IoT Example”
hi
when i send maximo update through rest api using
external system,publish channel and end point,
the json in update be like (contain rowstamp)
{
“_id”: “R18867-RAM”,
“_rowstamp”: “767476799”,
“description”: “az”,
“href”: “https:\/\/flsmidth.maximo.com\/maximo\/oslc\/os\/createpr\/_UjE4ODY3L1JBTQ–“,
“orgid”: “ACC”,
“pr1”: “QC”,
“prnum”: “R18867”,
“siteid”: “RAM”,
“status”: “NEW”,
“status_description”: “New PR”
}
i need not to add rowstamp, i found proerty called _Urs, but i don’t know how to use till now,
please help if you know
For outbound publish channel messages, you should be able to use Maximo’s JSON Mapping application to transform the JSON payload to a format that your external system understands.
The issue is the last element in your URL. It needs to be the REST ID of the Asset record you’re trying to update.
In the article’s example, the /_QkVERk9SRC8xMTQ1MA== represents a unique identifier for an Asset record that can be referenced in the MXASSET Object Structure. This identifier can be found be querying for the asset using an HTTP GET to the same MXASSET Object Structure, or it can be derived by base64 encoding the asset’s ASSETNUM + “/” + SITEID and prefixing that string with an underscore (“_”) character.
Hello, thank you very much for this!
Using what you say I’m trying to do a POST to os/mxincident however I’m having troubles just to get a response status = 200.
I executed this two requests:
POST: https://host_url//maximo/oslc/os/mxincident/ticketuid I get 400 with the message “oslc#create_on_updateuri”
POST: https://host_url//maximo/oslc/os/mxincident/ticketid I get 500 with the message “For input string: \”IN41321576\””
I don’t know what else to try… Do you have an advice to give me, please?
The issue is the last element in your URL. It needs to be the REST ID of the Incident record you’re trying to update.
In the article’s example, the /_QkVERk9SRC8xMTQ1MA== represents a unique identifier for an Asset record that can be referenced in the MXASSET Object Structure. This identifier can be found be querying for the asset using an HTTP GET to the same MXASSET Object Structure, or it can be derived by base64 encoding the asset’s ASSETNUM + “/” + SITEID and prefixing that string with an underscore (“_”) character.
Thanks for this, was playing with python and noticed params needed the ‘spi’ in front? Seems to work now, with API key this way, was unsure if there was a difference. Great trick with the unique identifier!
——-
import config
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
meterread=’100.00′ #your new reading, can put in params to json too
apikey= ‘apikeyxxxxxxxxxx’
‘oslc.select’: ‘assetuid’,
‘oslc.where’: ‘assetnum=12345’ #return the unique identifier from asset num
}
r=requests.get(url, headers=headers, params=params,verify=False)
x=r.json()
uniqueid= (x[‘rdfs:member’][0][‘rdf:about’]) #get the unique identifier in the URL string
url=uniqueid #unique identifier in the URL string.
params = {
Nice! You can use the lean=1 query parameter to avoid having to include the namespace prefixes.
In your HTTP GET you can include ‘lean’: ‘1’ in your params object. That should allow you to drop the rdfs: and rdf: prefixes from the initial response. Then you can append a ‘?lean=1’ to the HTTP POST and drop the spi: prefixes from the body of the request.
MxApprove End User License Agreement
If you agree to the terms of this MxApprove End User License Agreement (the “License Agreement”), click the Accept License Agreement button after reviewing the contents of this License Agreement to proceed with accessing the MxApprove (the “Application”). IF YOU DO NOT AGREE TO THE TERMS OF THE THIS LICENSE AGREEMENT, YOU WILL NOT HAVE ACCESS TO THE APPLICATION.
This is a license agreement between you, as the licensee and A3J Group LLC, a Delaware limited liability company, (“A3J”), its successors and assigns, its affiliated companies, and its authorized distributors and resellers as the licensor. This is not a contract for sale of the Application, but a license to use the Application subject to the terms and conditions of this License Agreement. Please read the terms carefully. You and A3J agree as follows:
Application.
The Application is the property of A3J. The term Application includes any related documentation, updates and permitted copies of the Application licensed to you by A3J. A3J expressly reserves all rights not expressly granted you.
Scope of License.
Upon your acceptance of the terms contained in this License Agreement, A3J grants you a nonexclusive, nontransferable, limited right to use the Application for personal or business use on the Licensed Devices, as defined below. The term "Use" means to install and access the Application in conjunction with the Application’s related and compatible software.
“Primary Device” shall mean the mobile device, tablet or other device compatible with applications owned or controlled by you, on which you download and install the Application and agree to be bound by the terms of this License Agreement and any other agreement associated with the Application. “Licensed Devices” shall mean the Primary Device and any other device that synchs or otherwise shares the same cloud or backup identification as the Primary Device.
This License Agreement does not allow you to use the Application on any device that you do not own or control. You may not distribute or make the Application available over a network where it could be used by multiple devices at the same time. You may not rent, lease, lend, sell, redistribute or sublicense the Application. You may not assign any right granted under this License Agreement without A3J’s prior written consent. You may not copy the Application. YOU AGREE THAT YOU WILL NOT MODIFY, ADAPT, TRANSLATE, ALTER NOR CREATE DERIVATIVE WORKS OF THE APPLICATION. YOU FURTHER AGREE THAT YOU WILL NOT REVERSE ENGINEER, DECOMPILE, DECRYPT, DISASSEMBLE, NOR SEEK TO DISCOVER THE SOURCE CODE OF THE APPLICATION OR ANY UPDATES ASSOCIATED THEREWITH. IF THE APPLICATION CONTAINS EMBEDDING BITS THAT LIMIT THE CAPABILITIES OF THE APPLICATION, YOU MAY NOT CHANGE OR ALTER THE EMBEDDING BITS.
Embedding of the Application is prohibited. You may NOT otherwise embed the Application. For example and without limitation: (i) You may NOT embed the Application into your hardware, software or other products, such as, application programs, electronic games, e-books, kiosks, printers, etc.; (ii) You may NOT embed the Application into your web pages; and (iii) You may NOT embed the Application into electronic commercial documents. This means that the Application may not be embedded or otherwise used in non-static files that may be accessed by computers or other devices that are NOT Licensed Devices.
A breach of these restrictions may subject you to prosecution and damages, including but not limited equitable relief in the form of an injunction.
Any updates or supplements to the Application will be governed by this License Agreement, unless a separate license agreement accompanies the update or supplement.
Intellectual Property Rights.
The Application, and any trademark, copyrights, patents, or any rights associated with the same, are the intellectual property of A3J. A3J reserves all of its rights under applicable laws. You acknowledge that the structure, organization and code of the Application are valuable trade secrets and confidential information of A3J and you shall not use this proprietary content, information or materials in any way except as expressly permitted under this License Agreement.
No Other Use.
You are granted only the rights expressly stated in this Agreement, and you may not use the Application for any other use or purpose. In addition to other prohibited uses described in this Agreement and without limitation, the following uses are specifically prohibited: (i) You may not share the Application with other individuals or business entities; (ii) You may not use the Application on more than the permitted Licensed Devices; (iii) You may not change the name of the Application; (iv) You may not translate the Application into other platforms.
Consent to Use Data.
A3J may collect and use technical data and related information, including but not limited to technical information about your device, system and application software gathered periodically to facilitate the provision of software updates, product support and other services related to the Application. A3J may use this information, provided this use does not personally identify you, to modify or further develop the Application and/or provide additional technologies to you.
Termination.
The license rights granted under this License Agreement are effective until terminated by you or A3J. Your rights under this License Agreement will terminate automatically without notice from A3J if you fail to comply with any of the term(s) of this License Agreement. Upon termination of the license, you shall cease all use of the Application, and destroy all copies, if any, full or partial, of the Application.
No Warranty.
YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT USE OF THE LICENSED APPLICATION IS AT YOUR SOLE RISK. TO THE EXTENT PERMITTED BY LAW, THE APPLICATION IS PROVIDED “AS-IS” AND “AS AVAILABLE,” WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND. A3J DOES NOT AND CANNOT WARRANT THE PERFORMANCE OR RESULTS YOU MAY OBTAIN BY USING THE APPLICATION. A3J MAKES NO WARRANTIES, CONDITIONS, REPRESENTATIONS OR TERMS, EXPRESS OR IMPLIED, WHETHER BY STATUTE, COMMON LAW, CUSTOM, USAGE OR OTHERWISE AS TO OTHER MATTERS, INCLUDING WITHOUT LIMITATION, NON INFRINGEMENT OF THIRD PARTY RIGHTS, TITLE, INTEGRATION, SATISFACTORY QUALITY, MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. FURTHER, A3J MAKES NO WARRANTIES AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE APPLICATION OR THAT THE APPLICATION WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION AND USE OF THE APPLICATION WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT DEFECTS IN THE APPLICATION WILL BE CORRECTED. IN THE EVENT THE APPLICATION PROVES DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES OR LIMITATIONS PLACED ON STATUTORY RIGHTS, SO THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
Damage Limitations.
TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL A3J BE LIABLE FOR PERSONAL INJURY, OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, LOSS OF DATA, BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE THE APPLICATION, HOWEVER CAUSED, REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF A3J HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. In no event shall A3J’s cumulative liability for any loss or damage to you (other than as may be required by applicable law in cases involving personal injury) exceed the amount of fifty dollars (US$50.00). The foregoing limitations will apply even if the above-stated remedy fails of its essential purpose.
No Export or Re-Export.
You may not use or otherwise export or “re-export” the Application. Specifically, and without limitation, you may not export or re-export the Application into (a) U.S. embargoed countries or (b) to anyone on the U.S. Treasury Department’s list of Specially Designated Nationals or the U.S. Department of Commerce Denied Person’s List or Entity List. By downloading and installing the Application and agreeing to the terms of this License Agreement you represent and warrant that you are not located in such a country or a person or entity on any such list. You further warrant and represent that you will not use the Application for any purpose prohibited by the laws of the United States.
Governing Law.
This Agreement is governed by the laws of the State of Florida, United States of America, excluding conflict of laws provisions and excluding the United Nations Convention on Contracts for the International Sale of Goods. You expressly agree that any disputes related to this Agreement will be resolved in the Circuit Court of Hillsborough County, Florida, U.S.A., or the United States District Court for the Middle District of Florida, U.S.A. Both you and A3J consent to the personal jurisdiction and venue of those courts. If any part of this Agreement is found void and unenforceable the balance of the Agreement will remain valid and enforceable according to its terms.
This License Agreement represents the entire agreement between you and A3J in connection with its subject matter. This License Agreement may only be modified by A3J in a writing that expressly states that the writing is intended to modify this License Agreement.
Contacting A3J.
A3J has a mailing address of 3225 S. MacDill Avenue, Tampa, Florida 33629, U.S.A. All support requests, completed registrations and other inquiries should be sent via e-mail to info@a3jgroup.com.
hi
when i send maximo update through rest api using
external system,publish channel and end point,
the json in update be like (contain rowstamp)
{
“_id”: “R18867-RAM”,
“_rowstamp”: “767476799”,
“description”: “az”,
“href”: “https:\/\/flsmidth.maximo.com\/maximo\/oslc\/os\/createpr\/_UjE4ODY3L1JBTQ–“,
“orgid”: “ACC”,
“pr1”: “QC”,
“prnum”: “R18867”,
“siteid”: “RAM”,
“status”: “NEW”,
“status_description”: “New PR”
}
i need not to add rowstamp, i found proerty called _Urs, but i don’t know how to use till now,
please help if you know
For outbound publish channel messages, you should be able to use Maximo’s JSON Mapping application to transform the JSON payload to a format that your external system understands.
im tryng to post this with postman
maxrest/oslc/os/mxwomobile/46693?lean=1
{ assetmeter:
[ { metername: ‘KEBOCORANMINYAK’,
assetnum: ‘877618’,
siteid: ‘TND’,
newreadingdate: ‘2020-08-13T08:43:34’,
newreading: ‘Bersih’,
inspector: ‘INSPEKSI.LUWUK’,
linearassetmeterid: 0 },
{ metername: ‘KONDISIFISIK’,
assetnum: ‘877618’,
siteid: ‘TND’,
newreadingdate: ‘2020-08-13T08:46:30’,
newreading: ‘Cacat Sirip Major’,
inspector: ‘INSPEKSI.LUWUK’,
linearassetmeterid: 0 }]}
but i get return 400 like this
{
“Error”: {
“reasonCode”: null,
“message”: “oslc#create_on_updateuri”,
“statusCode”: “400”
}
}
please help me
The issue is the last element in your URL. It needs to be the REST ID of the Asset record you’re trying to update.
In the article’s example, the /_QkVERk9SRC8xMTQ1MA== represents a unique identifier for an Asset record that can be referenced in the MXASSET Object Structure. This identifier can be found be querying for the asset using an HTTP GET to the same MXASSET Object Structure, or it can be derived by base64 encoding the asset’s ASSETNUM + “/” + SITEID and prefixing that string with an underscore (“_”) character.
Hello, thank you very much for this!
Using what you say I’m trying to do a POST to os/mxincident however I’m having troubles just to get a response status = 200.
I executed this two requests:
POST: https://host_url//maximo/oslc/os/mxincident/ticketuid I get 400 with the message “oslc#create_on_updateuri”
POST: https://host_url//maximo/oslc/os/mxincident/ticketid I get 500 with the message “For input string: \”IN41321576\””
I don’t know what else to try… Do you have an advice to give me, please?
The issue is the last element in your URL. It needs to be the REST ID of the Incident record you’re trying to update.
In the article’s example, the /_QkVERk9SRC8xMTQ1MA== represents a unique identifier for an Asset record that can be referenced in the MXASSET Object Structure. This identifier can be found be querying for the asset using an HTTP GET to the same MXASSET Object Structure, or it can be derived by base64 encoding the asset’s ASSETNUM + “/” + SITEID and prefixing that string with an underscore (“_”) character.
Thanks for this, was playing with python and noticed params needed the ‘spi’ in front? Seems to work now, with API key this way, was unsure if there was a difference. Great trick with the unique identifier!
——-
import config
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
meterread=’100.00′ #your new reading, can put in params to json too
apikey= ‘apikeyxxxxxxxxxx’
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
host = ‘https:/host_url/maximo’ #dev
url=’/maximo/oslc/os/mxasset’
url = host + url #renamed for DEV.Testing
headers = {
‘apikey’: apikey,
‘properties’: ‘*’,
‘Content-Type’: “application/json”,
‘x-method-override’: ‘PATCH’,
‘patchtype’: ‘MERGE’
}
params = {
‘oslc.select’: ‘assetuid’,
‘oslc.where’: ‘assetnum=12345’ #return the unique identifier from asset num
}
r=requests.get(url, headers=headers, params=params,verify=False)
x=r.json()
uniqueid= (x[‘rdfs:member’][0][‘rdf:about’]) #get the unique identifier in the URL string
url=uniqueid #unique identifier in the URL string.
params = {
“spi:assetmeter”: [
{
‘spi:inspector’ : ‘JOEY’,
‘spi:newreadingdate’ :’&SYSDATE&’,
“spi:metername”: “FLOAT”,
“spi:linearassetmeterid”: 0,
“spi:newreading”: meterread #from ‘meterread=’100.00′ #your new reading’
}
]
}
r=requests.post(url, headers=headers, json=params,verify=False)
pprint(r.status_code)
Nice! You can use the lean=1 query parameter to avoid having to include the namespace prefixes.
In your HTTP GET you can include ‘lean’: ‘1’ in your params object. That should allow you to drop the rdfs: and rdf: prefixes from the initial response. Then you can append a ‘?lean=1’ to the HTTP POST and drop the spi: prefixes from the body of the request.