Skip to content

IBM Maximo Connector

The MaximoConnector integrates Machina with IBM Maximo Manage (EAM), reading and creating maintenance data via the OSLC/JSON REST API.

Prerequisites

  • IBM Maximo Manage instance (7.6.0.2+ or Maximo Application Suite)
  • API key (recommended), or Basic/MAXAUTH credentials
  • Network access to the Maximo OSLC endpoints (/maximo/oslc/os/)

Installation

pip install machina-ai[cmms-rest]

Configuration

from machina.connectors import Maximo
from machina.connectors.cmms import ApiKeyHeaderAuth
from machina.domain.asset import AssetType

connector = Maximo(
    url="https://maximo.example.com",
    auth=ApiKeyHeaderAuth(header_name="apikey", value="your-api-key"),
    asset_type_map={
        "PUMPS": AssetType.ROTATING_EQUIPMENT,
        "VESSELS": AssetType.STATIC_EQUIPMENT,
        "INSTRUMENTS": AssetType.INSTRUMENT,
    },
)
await connector.connect()
from machina.connectors import Maximo
from machina.connectors.cmms import BasicAuth

connector = Maximo(
    url="https://maximo.example.com",
    auth=BasicAuth(username="maxadmin", password="secret"),
)
await connector.connect()
connectors:
  cmms:
    type: maximo
    url: https://maximo.example.com
    auth:
      type: api_key
      header_name: apikey
      value: ${MAXIMO_API_KEY}

Capabilities

Capability Description
read_assets Read asset records (mxasset object structure)
read_work_orders Read work orders — filter by asset_id and/or status (accepts WorkOrderStatus enum or raw Maximo code)
create_work_order Create new work orders
update_work_order Update status, assignee, or description via PATCH
read_spare_parts Read inventory items (mxinventory object structure)
read_maintenance_plans Read PM triggers (mxpm object structure)

Convenience methods

These methods are available but are not declared as agent-discoverable capabilities:

Method Description
get_work_order(wonum) Fetch a single work order by wonum
close_work_order(wonum) Transition to CLOSED (Maximo CLOSE) via update_work_order
cancel_work_order(wonum) Transition to CANCELLED (Maximo CAN) via update_work_order

Usage Examples

Read assets

assets = await connector.read_assets()
for asset in assets:
    print(f"{asset.id}: {asset.name} (criticality: {asset.criticality})")

Filter work orders with Machina enum

from machina.domain.work_order import WorkOrderStatus

wos = await connector.read_work_orders(
    asset_id="PUMP-201",
    status=WorkOrderStatus.IN_PROGRESS,  # auto-mapped to Maximo "INPRG"
)

Get a single work order

wo = await connector.get_work_order("WO-001")
if wo:
    print(f"{wo.id}: {wo.failure_mode}{wo.failure_cause}")

Create a work order

from datetime import datetime, timezone
from machina.domain import WorkOrder, WorkOrderType, Priority

wo = WorkOrder(
    id="",
    type=WorkOrderType.CORRECTIVE,
    priority=Priority.HIGH,
    asset_id="PUMP-201",
    description="Replace mechanical seal",
    created_at=datetime.now(tz=timezone.utc),
    updated_at=datetime.now(tz=timezone.utc),
)
created = await connector.create_work_order(wo)
print(f"Created: {created.id}")

Update / close a work order

from machina.domain.work_order import WorkOrderStatus

updated = await connector.update_work_order(
    "WO-001",
    status=WorkOrderStatus.COMPLETED,
    assigned_to="john.doe",
)
await connector.close_work_order("WO-001")

Asset Type Mapping

Maximo does not expose a direct equipment-type field. By default, all assets are classified as ROTATING_EQUIPMENT. Provide an asset_type_map to override based on your Maximo classstructureid (or assettype) values:

from machina.domain.asset import AssetType

connector = Maximo(
    url="https://maximo.example.com",
    auth=auth,
    asset_type_map={
        "PUMPS": AssetType.ROTATING_EQUIPMENT,
        "VESSELS": AssetType.STATIC_EQUIPMENT,
        "INSTRUMENTS": AssetType.INSTRUMENT,
        "MOTORS": AssetType.ELECTRICAL,
    },
)

Unmapped values fall back to ROTATING_EQUIPMENT.

Entity Mapping

Maximo Field Machina Field
assetnum Asset.id
description Asset.name
location Asset.location
priority (1-3) Asset.criticality (A/B/C)
classstructureid Asset.type (via asset_type_map)
wonum WorkOrder.id
worktype WorkOrder.type (CM→Corrective, PM→Preventive, CP→Predictive, EV→Improvement)
wopriority WorkOrder.priority (1→Emergency, 2→High, 3→Medium, 4→Low)
status WorkOrder.status (WAPPR→Created, APPR→Assigned, INPRG→InProgress, COMP→Completed, CLOSE→Closed, CAN→Cancelled)
failurecode WorkOrder.failure_mode
failureremark / problemcode WorkOrder.failure_cause
itemnum SparePart.sku
curbal SparePart.stock_quantity
pmnum MaintenancePlan.id
frequency MaintenancePlan.interval.days

Resilience

All HTTP calls route through a shared retry helper with exponential backoff. See SAP PM Connector — Resilience for details.

Known Limitations

  • Object structure customisation: The connector targets standard Maximo object structures (mxasset, mxwo, mxinventory, mxpm). Custom object structures require subclassing.
  • Spare parts by asset: Maximo's mxinventory does not directly link to assets. Filtering spare parts by asset_id is not supported; use work-order job plans instead.
  • Pagination: Uses Maximo's OSLC responseInfo.nextPage link-following. Very large result sets may benefit from server-side oslc.where filtering.

API Reference

MaximoConnector

MaximoConnector(*, url: str, auth: _AuthUnion, lean: bool = True, asset_type_map: dict[str, AssetType] | None = None)

Connector for IBM Maximo Manage.

Provides integration with Maximo's OSLC/JSON REST API for reading and creating maintenance data.

Parameters:

Name Type Description Default
url str

Base URL of the Maximo instance (e.g. https://maximo.example.com).

required
auth _AuthUnion

Authentication strategy — :class:ApiKeyHeaderAuth, :class:BasicAuth, or :class:BearerAuth.

required
lean bool

If True (default), requests add lean=1 to suppress OSLC namespace wrappers in responses.

True
asset_type_map dict[str, AssetType] | None

Optional mapping from a Maximo classification key (classstructureid preferred, assettype as fallback) to a Machina :class:AssetType. When omitted, every Maximo asset is mapped to :attr:AssetType.ROTATING_EQUIPMENT. Use this to honour your site's Maximo taxonomy without subclassing the connector.

None
Example
from machina.connectors import Maximo
from machina.connectors.cmms import ApiKeyHeaderAuth
from machina.domain.asset import AssetType

connector = Maximo(
    url="https://maximo.example.com",
    auth=ApiKeyHeaderAuth(header_name="apikey", value="my-key"),
    asset_type_map={
        "PUMPS": AssetType.ROTATING_EQUIPMENT,
        "VESSELS": AssetType.STATIC_EQUIPMENT,
        "INSTRUMENTS": AssetType.INSTRUMENT,
    },
)
await connector.connect()
assets = await connector.read_assets()

connect async

connect() -> None

Verify credentials against the Maximo API.

Performs a lightweight request to the whoami endpoint.

Raises:

Type Description
ConnectorAuthError

If credentials are invalid.

ConnectorError

If the server is unreachable.

disconnect async

disconnect() -> None

Close the connector.

health_check async

health_check() -> ConnectorHealth

Return current health status.

read_assets async

read_assets() -> list[Asset]

Return all assets from Maximo (MXASSET object structure).

get_asset async

get_asset(asset_id: str) -> Asset | None

Look up a single asset by asset number.

read_work_orders async

read_work_orders(*, asset_id: str = '', status: WorkOrderStatus | str = '') -> list[WorkOrder]

Read work orders, optionally filtered by asset or status.

Parameters:

Name Type Description Default
asset_id str

Filter by Maximo asset number.

''
status WorkOrderStatus | str

Filter by status — accepts a :class:WorkOrderStatus enum (reverse-mapped to Maximo code) or a raw Maximo status string for backward compatibility.

''

get_work_order async

get_work_order(work_order_id: str) -> WorkOrder | None

Look up a single work order by work order number.

create_work_order async

create_work_order(work_order: WorkOrder) -> WorkOrder

Create a new work order in Maximo.

Parameters:

Name Type Description Default
work_order WorkOrder

Machina :class:WorkOrder to create.

required

Returns:

Type Description
WorkOrder

The created work order with the server-assigned wonum.

update_work_order async

update_work_order(work_order_id: str, *, status: WorkOrderStatus | None = None, assigned_to: str | None = None, description: str | None = None) -> WorkOrder

Update an existing work order in Maximo via PATCH.

Only non-None fields are included in the PATCH payload.

Parameters:

Name Type Description Default
work_order_id str

Maximo work order number (wonum).

required
status WorkOrderStatus | None

New status (reverse-mapped to Maximo code).

None
assigned_to str | None

New lead person.

None
description str | None

New work order description.

None

Returns:

Type Description
WorkOrder

The updated work order.

close_work_order async

close_work_order(work_order_id: str) -> WorkOrder

Transition a work order to CLOSED status.

cancel_work_order async

cancel_work_order(work_order_id: str) -> WorkOrder

Transition a work order to CANCELLED status.

read_spare_parts async

read_spare_parts(*, sku: str = '') -> list[SparePart]

Read inventory items (spare parts) from Maximo.

Parameters:

Name Type Description Default
sku str

Optional Maximo itemnum to narrow the lookup via an OSLC where clause.

''
Note

Maximo's mxinventory object structure does not expose a direct asset-compatibility relation, so filtering by asset is not supported here. For asset-specific spare parts, consult the corresponding work-order job plan or mxpmpart.

read_maintenance_plans async

read_maintenance_plans() -> list[MaintenancePlan]

Read preventive-maintenance triggers from Maximo.

read_maintenance_history async

read_maintenance_history(asset_id: str) -> list[WorkOrder]

Return completed/closed work orders for an asset.