Asset Service Overview

Asset Service Overview

Use the Asset service to create, update, and store asset model data that defines asset properties and relationships between assets and other modeling elements.

The Predix Asset service provides REST APIs to support asset modeling. Application developers use the Asset service to create, update, and store asset model data that defines asset properties as well as relationships between assets and other modeling elements. Data consumers can quickly retrieve vast amounts of asset data, while developers can store asset instance data. For example, an application developer can create an asset model describing the logical component structure of all pumps in an organization, then create instances of the model to represent each pump in an organization. Developers can also create custom modeling objects to meet their unique domain needs. The Asset service consists of an API layer, a query engine, and a graph database. Asset audit history enables you to update asset descriptions and retrieve historical information about your assets.

Figure: Asset Service Components


The Asset service includes the following components:
  • REST API layer

    Client applications can access asset data using Asset service REST API endpoints. These endpoints provide a JSON interface where you can post the data that describes all of your assets. To use these APIs, your application makes HTTPS requests and parses the response. You can use any web-development language to access the APIs.

  • Representation layer

    The representation layer translates data from JSON to internal graph representation and back to JSON.

  • Query engine

    The query engine enables developers to use JSON and Graph Expression Language (GEL) to retrieve data about any object or any object property in the Asset service data store. See asset-service-using.html#reference_63400152-e3b8-4240-a1fd-5733e532ab3c.

  • Audit History service

    The Asset audit history service provides APIs that enable you to retrieve historical information about REST requests in your Asset service repositories.

  • Cassandra graph database

    The Asset service stores data in an Apache Cassandra NoSQL graph database. See asset-service-overview.html#reference_08d19859-2583-4a4c-b58f-06e3875f4ab9.

Additional Information

Exploring Asset Service Guides

Graph-based Data Model Basics

The Asset service is based on a graph data model and it stores data in a graph database.

To understand why we use a graph data model, here is a comparison of relational, hierarchical, and graph data models:

Relational data modelHierarchical data modelGraph data model
Tables are related by primary key. The relations in a relational database are handled by joins between tables. These can be managed in a permanent declarative fashion by the use of foreign keys, or in a temporary fashion by ad-hoc joins in the queries. A typical query language is Structured Query Language (SQL). Parent nodes have more intrinsic importance. A typical query language is Extensible Markup Language (XML).A graph consists of resources related to other resources, with no single resource having any intrinsic importance over another. A typical query language is Resource Description Framework (RDF). In a graph-based data model (RDF graph), the syntax comprises a subject, a predicate, and an object.
We selected a graph database (graph db) model for the Asset Data Service based on the needs of businesses in the era of the Industrial Internet of Things (IIoT). In the IIOT age, developers face many challenges:
  • How to store huge numbers of assets and related objects.
  • How to define huge numbers of relationships between assets and other objects.
  • How to organize and make sense of them.
  • How to discover and query relationships among them.
The necessity to define and query relationships is what drives the need for a graph db. Relationships are take priority in a graph db. They are built upon defining relationships between objects and providing performant queries on those relationships. Consider this diagram:


In the pre-IIOT era (shown above the dotted line), customers often had data relevant to an asset stored in typical “alphabet soup” or legacy systems – SCM, EAM, PLM, CRM, and so on. In the IIOT era (below the dotted line), there are many disparate sets of data that are relevant to an asset. For example:
  • Streaming time-series data coming from sensors.
  • Unstructured data such as audio, video, and documentation.
  • Advanced operations data.
  • Data from connected devices.
  • Weather information.
The list goes on and on.

Many of these data elements may have relationships with one another in addition to linkage with a specific asset or assets. The ecosystem that an asset lives in is getting richer and more complex over time. Understanding and querying on the relationships this data has to your assets is why the graph db and query capability of Asset service is extremely important.

Use Graph Expression Language (GEL) in the filter clause of an API request to run a query against Asset service data. See asset-service-using.html#concept_828157be-2bee-44dd-b154-714f242bd175.

Asset Modeling

An asset model represents the information that you are storing about your domain objects, how your objects are organized, and how they are related.

As an application developer, you can use the Asset service APIs to define a consistent asset model and a hierarchical structure for your data. In an Asset service model, each piece of physical equipment is represented by an asset instance. You can organize your domain objects by classification and by any number of custom modeling objects. The Asset service provides an open model.

Asset service domain objects are distinct entities that a customer manages and tracks. All of the elements that make up the asset model, such as Classifications, are domain objects. The Assets entity is also a domain object. Any distinct entity defined by a customer is considered a domain object. Use JSON to describe the domain objects in your asset model. Objects are unordered sets of name-value pairs, and each object has a unique URI. The URI is like a primary key in that it uniquely identifies an asset instance stored in the graph database. The Asset service requires well-formed JSON, which can be validated with available tools such as the validator at http://jsonlint.com/.

The count of distinct domain objects provides a measure of the complexity and richness of an asset model. The count of instances of domain objects indicates the scope of the asset model. For example:

Domain ObjectsDomain Object Instances
Assets1000
Classifications200
Part Numbers100
Tags5000
Templates100
Number of distinct domain objects: 5Total number of instances: 6,400

For example, an organization can use a countries object to store data about where its pumps are manufactured and a manufacturers object to store data about specific pump suppliers. It can use several classifications of Pumps to define pump types, and it can assign multiple attributes, such as Brass or Steel, to each classification. The organization can also associate multiple sensors, such as Flow or Pressure, to a classification.

The Asset service APIs support assets, classifications, and custom domain modeling objects.

API CategoryDescription
AssetsTypically, you define your assets in a hierarchical structure composed of a parent asset and one or many peers and children. You can associate an asset with a classification or any number of custom modeling objects. Assets can have any number of customer-defined attributes.

An asset can also “stand alone” in the system, not associated with any other modeling elements.

Classifications

Classifications are arranged in a tree structure and provide a means to group similar assets and to track common attributes. A classification can point to multiple assets. Attributes can be assigned at any level in the classification hierarchy.

Custom modeling objects

Custom modeling objects are hierarchies that you can use to provide more information about your assets. For example, you can create separate objects for asset location, manufacturer, and service contract. A location can be associated with multiple assets. Likewise, an individual asset can be associated with multiple locations.

The following domain object examples show hierarchy diagrams and associated JSON code for a simple asset model composed of the following objects: classifications, countries, manufacturers, and pumps.

For a more robust data set that you can use to run sample queries, see asset-service-asset-model.html#reference_99274c09-7d07-40fe-95a7-3219cd905ca1

Data Validation Rules

The JSON schemas that define your domain objects also define your data validation rules. After you upload a new or updated schema, Asset automatically validates any new data ingested against the new schema. Data ingested previously will not be validated automatically against the new or updated schema.

JSON Schema validation requirements:
  • The schema must be compliant with JSON schema format.
  • The entity type must be type 'object'.
  • The schema must include a URI property and the URI must be in compliance with Asset default URI rules. See asset-service-using.html#reference_63400152-e3b8-4240-a1fd-5733e532ab3c
  • You may add to a schema previously uploaded, but you cannot change the data type of any schema previously defined.

Best Practices for Data Validation

Because data previously ingested is not validated automatically, you might have data that does not match your new schema. GE recommends that you update your existing data to avoid receiving errors during queries on that data.

Classifications Object Example

The Pumps classification has two child classifications: positiveDisplacementPumps and kineticPumps. The kineticPumps classification has one child: centrifugalPumps, which in turn has a child: axialPumps. The axialPumps classification is associated with an attribute: Brass.

Figure: Classification Object Hierarchy
Note: The value of the uri must be unique so that it may be referenced from other arrays. You may use a GUID or UUID, or an alphanumeric string as the value, so long as it is unique.
[
  {
    "uri": "/classifications/Pumps1",
    "name": "Pumps",
    "description": "Parent Classification of Pumps",
    "attributes": {
      "Fuel Injector":{
        "type": "string",
        "value": ["Normal"]
      }
    },
    "parameter": {
      "ElectronicThrottlePositionSensor":
      {
        "parameterUri": "/parameter/ElectronicThrottlePositionSensor1",
        "parameterId":"ElectronicThrottlePositionSensor1"
      }
    }
  },
  {
    "uri": "/classifications/positiveDisplacementPumps1",
    "name": "Positive Displacement Pumps",
    "description": "positive Displacement Pumps Classification",
    "parent": "/classifications/Pumps1",
    "attributes": {
      "Manifold bolts":{
        "type": "number",
        "value": 8
      },
      "Manifold gasket":{
        "type": "number",
        "value": 1
      }
    }
  },
  {
    "uri": "/classifications/kineticPumps1",
    "name": "Kinetic Pumps",
    "description": "Kinetic Pumps Classification",
    "parent": "/classifications/Pumps1",
    "attributes": {
    }
  },
  {
    "uri": "/classifications/centrifugalPumps1",
    "name": "Centrifugal Pumps",
    "description": "Centrigugal Pumps Classification",
    "parent": "/classifications/kineticPumps1",
    "attributes": {
    }
  },
  {
    "uri": "/classifications/axialPumps1",
    "name": "Axial Pumps",
    "description": "Axial Pumps Classification",
    "parent": "/classifications/centrifugalPumps1",
    "attributes": {
      "displayName": {
        "type": "string",
        "value": ["Brass"]
      }
    }
  }

]

Countries Object Example

The custom Countries modeling object has two children: USA and Japan.

Figure: Locations Object

    [
  {
    "uri": "/locations/countries",
    "name": "Countries",
    "attributes": {
    }
  },
  {
    "uri": "/locations/USA",
    "name": "USA",
    "parent": "/locations/countries",
    "attributes": {
    }
  },
  {
    "uri": "/locations/Japan",
    "name": "Japan",
    "parent": "/locations/countries",
    "attributes": {
    }
  }
]
  

Manufacturers Object Example

The custom manufacturers modeling object has two children: JohnBluePumps and KachengoPumps. KachengoPumps has two attributes: Official Manufacturer Name and Alias.

Figure: Manufacturers Object

[
  {
    "uri": "/manufacturers/PumpManufacturers1",
    "name": "Pump Manufacturers",
    "description":  "Parent of Pump Manufacturers",
    "attributes": {
    }
  },
  {
    "uri": "/manufacturers/JohnBluePumps",
    "name": "John Blue Pumps",
    "parent": "/manufacturers/PumpManufacturers1",
    "attributes": {
    }
  },
  {
    "uri": "/manufacturers/KachengoPumps",
    "name": "Kachengo Pumps",
    "parent": "/manufacturers/PumpManufacturers1",
    "attributes": {
      "Official Manufacturer Name": {
        "type": "string",
        "value": ["Kachengo Pumps, Limited"]
      },
      "Alias": {
        "type": "string",
        "value": ["Kachengo"]
      }
    }
  }
]

Pumps Object Example

There are two pump instances in this example: Pump1Axial and Pump2Positive Displacement.

Figure: Pump Objects
[{
	"uri": "/pumps/Pump1Axial",
	"classification": "/classifications/Axial",
	"manufacturer": "/manufacturers/KachengoPumps",
	"countries": "/countries/Japan",
	"nonserialized": {
	
	},
	"attributes": {
		"Name": {
			"type": "string",
			"value": ["Pump 1 Axial"]
		},
		"createdOn": {
			"type": "string",
			"value": ["2015-02-20T00:00:00+0000"]
		},
		"updatedOn": {
			"type": "string",
			"value": ["2015-02-20T00:00:00+0000"]
		},
		"isActive": {
			"type": "boolean",
			"value": [true]
		}
	}
},
{
	"uri": "/pumps/Pump2PositiveDisplacement",
	"classifications": "/classifications/PositiveDisplacement",
	"manufacturers": "/manufacturers/JohnBluePumps",
	"countries": "/countries/USA",
	"nonserialized": {
		
	},
	"attributes": {
		"Name": {
			"type": "string",
			"value": ["Pump 2 Positive Displacement"]
		},
		"createdOn": {
			"type": "string",
			"value": ["2015-02-20T00:00:00+0000"]
		},
		"updatedOn": {
			"type": "string",
			"value": ["2015-02-20T00:00:00+0000"]
		},
		"isActive": {
			"type": "boolean",
			"value": [true]
		}
	}
}]

For a more robust data set that you can use to run sample queries, see asset-service-asset-model.html#reference_99274c09-7d07-40fe-95a7-3219cd905ca1.

About Asset Audit History

The Asset audit history service provides APIs that enable you to retrieve historical information about REST requests in your Asset service repositories.

Before you begin, you must configure your audit metadata in your request headers. See asset-service-using-history.html#reference_c61144d3-a00d-42b9-b09b-acdd0bf91409.

The audit history APIs provide the following endpoints:
  • /<predix-asset-url>/system/configs

    The audit history service is disabled by default. Use this endpoint to enable or disable the asset audit history service.

  • /<predix-asset-url>/system/audit

    Use this endpoint to retrieve the old values and the new values of the requested assets.

  • /<predix-asset-url>/system/audit/changes

    Use this endpoint to retrieve an old value and a new value record for each element in a collection that has changed.

  • /<predix-asset-url>/system/audit/snapshots

    Use this endpoint to retrieve details about a single asset at a moment in time.