Generating a Work Order to MaintainX from Ignition?

Good afternoon,

I am interested in trialing the CMMS platform MaintainX. Specifically, I would like to automatically generate a work order when a process variable exceeds a set limit.

Currently, I will be using an MQTT broker (the distributor) but I am unsure how to transfer information from Ignition to MaintainX. I understand that it likely needs to be done via an API, but I am unfamiliar with the process. Would an additional platform need to sit between the Ignition broker and MaintainX?

Any advice to point me in the right direction would be greatly appreciated.

Thanks,
Ryan

Also apologies if this is not the corret place to ask this question.

Well, it sounds like you're speccing yourself into trying to use MQTT to transfer information, in which case you would have to either explicitly publish the information to topics in the broker or rely on tags being published via MQTT Engine.

This is probably the wrong approach though. Integration with systems like this is typically done via web service calls. You can make HTTP calls from Ignition scripting using the system.net.httpClient function, and you can receive inbound HTTP calls using the WebDev module.

2 Likes

Going off of what Kevin said, I would use an HTTP client and not overcomplicate things with MQTT. This is even more so the case, since MaintainX seems to have a pretty APIs and documentation on their site:

The screenshot above is for creating a work order, so as long as you have or can generate those fields in Ignition to pass into the body of the API call, you should be able to do this. One thing I would look into is whether the API layer is free or not - you'll need to make an API key, which may require an account, etc. There are also usually rate limits with APIs for modern web services, to avoiding overloading their system, so if you are generating 10 work orders per second (theoretically), some requests may be dropped. Again, I haven't read through their rate limit documentation, I just made those numbers up, but you get the idea....

Hey,

Thank you for your response. Based on your instructions, I've managed to create a work order using Postman, leveraging my MaintainX account.

Now, I'm curious about integrating this process with Ignition. How would I go about linking Ignition to MaintainX? Since I can establish a connection with Postman, I assume the content is good; I just need guidance on addressing MaintainX from Ignition.

I've reviewed the Webdev notes in Ignition, but I must admit, I'm quite inexperienced in this area. Any assistance would be greatly appreciated."

Thanks,

Ryan

I don't believe you'll need the WebDev module - that is helpful when you want to host resources, not necessarily when you want to read/write resources to somewhere else.

You could just use the system.net.httpClient object and a few helper methods to accomplish what you want. If you post a screenshot of your Postman setup (blur out any authentication), then I can give you an approximation of what the equivalent in Ignition is.

1 Like

@YF129701 Thanks for the help, I really do appreciate it.

Here is the details I think you are after.

And here is the code example:

//Want to look up assest online or offline
{
    "title": "Inspection of Water Pump #1 PN:111 (Pump House), Vibration Warning",
    "assetId": 5054334,
    "assignees": [
        {
            "id": 82364,
            "type": "TEAM" // dont know what this means
        }
    ],
    "estimatedTime": 1800,
    "categories": [
        "Inspection",
        "Damage"
    ],
    "description": "Whenever irregularities in the water pump operation arise, our established procedure initiates a comprehensive inspection of the pump system in our facility. This encompasses assessing the condition of filters for timely replacement. Technicians conducting the inspection will sign off upon completion to facilitate tracking of maintenance activities.",
    "locationId": 1921018,
    "priority": "HIGH",
    "procedure": {
        "id": 1711611,
        "title": "Alert Triggered Water Pump Inspection",
        "fields": [
            {
                "type": "HEADING",
                "label": "Warning: Only authorized technicians should perform this inspection."
            },
            {
                "type": "INSPECTION_CHECK",
                "label": "Check for visible signs of damage to Water Pump"
            },
            {
                "type": "TEXT",
                "label": "If visible damage, state pumps condition on arrival"
            },
            {
                "type": "NUMBER",
                "label": "Record the current pressure reading of Water Pump Keyence Flow meter (from SCADA or From digital display on meter)."
            },
            {
                "type": "INSPECTION_CHECK",
                "label": "Inspect and verify the condition of the pump filters."
            },
            {
                "type": "TEXT",
                "label": "Inspect and verify the condition of the pump exterior."
            },
            {
                "type": "FILE",
                "label": "Upload a photo of the pump's condition"
            },
            {
                "type": "SIGNATURE",
                "label": "Technician's signature upon completion of the inspection."
            }
        ]
    }
}```

Yep, those are great! Just a few more things so I can get as close as possible - can you send the Body and Headers panes in Postman?

Like so:

and

This,


and this,

On the headers snip, can you hit the 8 hidden and show what's in there? What I'm looking for is the bearer token - it should be part of the header iirc.

Here's a preliminary first try at converting Postman to Ignition httpClient. Replace the token variable with your token. You can run this in the Script Console, at least to try it out.

The code
# Create the JythonHttpClient 
client = system.net.httpClient()

url = "https://api.getmaintainx.com/v1/workorders"
body = {
    "title": "Inspection of Water Pump #1 PN:111 (Pump House), Vibration Warning",
    "assetId": 5054334,
    "assignees": [
        {
            "id": 82364,
            "type": "TEAM"
        }
    ],
    "estimatedTime": 1800,
    "categories": [
        "Inspection",
        "Damage"
    ],
    "description": "Whenever irregularities in the water pump operation arise, our established procedure initiates a comprehensive inspection of the pump system in our facility. This encompasses assessing the condition of filters for timely replacement. Technicians conducting the inspection will sign off upon completion to facilitate tracking of maintenance activities.",
    "locationId": 1921018,
    "priority": "HIGH",
    "procedure": {
        "id": 1711611,
        "title": "Alert Triggered Water Pump Inspection",
        "fields": [
            {
                "type": "HEADING",
                "label": "Warning: Only authorized technicians should perform this inspection."
            },
            {
                "type": "INSPECTION_CHECK",
                "label": "Check for visible signs of damage to Water Pump"
            },
            {
                "type": "TEXT",
                "label": "If visible damage, state pumps condition on arrival"
            },
            {
                "type": "NUMBER",
                "label": "Record the current pressure reading of Water Pump Keyence Flow meter (from SCADA or From digital display on meter)."
            },
            {
                "type": "INSPECTION_CHECK",
                "label": "Inspect and verify the condition of the pump filters."
            },
            {
                "type": "TEXT",
                "label": "Inspect and verify the condition of the pump exterior."
            },
            {
                "type": "FILE",
                "label": "Upload a photo of the pump's condition"
            },
            {
                "type": "SIGNATURE",
                "label": "Technician's signature upon completion of the inspection."
            }
        ]
    }
}
token = "<your_bearer_token_here>"		# your bearerToken env variable here

headers = {
	"Content-Type": "application/json",
	"Accept": "application/json",
	"Authorization": "Bearer {}".format(token)		
}
 
# Sent a POST request (blocking)
response = client.post(url, data=body, headers=headers)
 
# Validate the response
if response.good:
    # Do something with the response
    print response.getJson()
[details="Summary"]
This text will be hidden
[/details]

It takes a little tweaking to get the authorization working sometimes, so I wouldn't be surprised if you got an error. I would actually be shocked if you didn't get an error.

1 Like

Sorry, here is the complete header

Try the code in the post just above this one - I think the Authorization needs to be tweaked, but if you run it, you'll probably get an error message that points you in the right direction.

I owe you a beer my friend! It worked first time!

It was complaining about the:

[details="Summary"]
This text will be hidden
[/details],

But after removing no troubles.

1 Like

Damn now I'm scared... My code never works first time :ghost:

2 Likes

Hahah now you know you must be an expert! Thanks mate, really appreciate it.