# Model.Update Request

Update an object model (aka requested model) in IM.

Fully replaces the object model's properties and variables with the provided ones and updates the version.

'model.update' action message is sent to the platform by a directly connected device (i.e. Edge) via IoTHub.

The requested model must exist in information model service.

# Idempotency

The model.update message is Idempotent. This means that sending several identical requests will result in the model being updated successfully in the Info Model Service:

  • The first update of an existing object model (determined via objectId + model) will be successful.
  • Subsequent updates of this object model will be rejected due to an object model version mismatch.

# Event Properties

# Unique to model.update Request

Property Mandatory Description
objectId Mandatory Object identifier, must be in GUID format.
model Optional Model definition identifier (modelId). Any model, including abb.ability.device, is supported. Defaults to abb.ability.device.

# Message body

The message body should be JSON compliant to the request payload format of PUT /objects/{objectId}/models/{modelId} operation.

# Message Format

{
  "properties": {
    "iothub-connection-device-id": "<authenticated device id>",
    "msgType": "action",
    "action": "model.update",
    "version": 2,
    "correlationId": "<correlation id>",
    "objectId": "<GUID>",
    "model": "<model definition>",
    "ack": "<ack>",
    "target": "<connected device path>",
    "timeout": "<integer>"
  },
  "body": "<body>"
}

# IM Requirements

A unique property cannot be changed. This ensures the possibility that the object model of a certain type can be substituted with any object model of a child type.

The object model is made unique by the typeId and by unique properties values if the values are unique within the uniqueness group.

General Example:

{
  "model":"abb.ability.device",
  "typeId":"Type.E",
  "version":"1.0.0",
  "baseTypes": ["Type.C@1.0.0"],
  "unique": ["velocity"],
  "properties":{
    "velocity":{
      "dataType":"number",
      "isMandatory": true,
      "description":"Device request processing speed per minute"
   }
  }
}
{
  "model":"abb.ability.device",
  "typeId":"Type.E",
  "version":"1.0.0",
  "baseTypes": ["Type.C@1.0.0"],
  "unique": ["serialNumber", "velocity"],
  "properties":{
    "velocity":{
      "dataType":"number",
      "isMandatory": true,
      "description":"Device request processing speed per minute"
   }
  }
}

Example Valid Modification:

{
  "model":"abb.ability.device",
  "typeId":"Type.Q",
  "version":"1.0.0",
  "properties":{
    "serialNumber":{
      "dataType":"string",
      "isMandatory": true
   }
 }
}
{
  "typeId": "Type.A",
  "version": "1.0.0",
  "baseTypes": ["Type.Q@1.0.0"],
  "model": "abb.ability.device",
  "unique": [ "serialNumber" ]
}
{
  "model":"abb.ability.device",
  "typeId":"Type.W",
  "version":"1.0.0",
  "properties":{
    "serialNumber":{
      "dataType":"string",
      "isMandatory": true
   }
 }
}
{
  "typeId": "Type.A",
  "version": "2.0.0",
  "baseTypes": ["Type.W@1.0.0"],
  "model": "abb.ability.device",
  "unique": [ "serialNumber" ]
}

Example Invalid Modification:

{
  "model":"abb.ability.device",
  "typeId":"Type.E",
  "version":"1.0.0",
  "unique": ["velocity"],
  "properties":{
    "velocity":{
      "dataType":"number",
      "isMandatory": true,
      "description":"Device request processing speed per minute"
   }
  }
}
{
  "model":"abb.ability.device",
  "typeId":"Type.Q",
  "version":"1.0.0",
  "properties":{
    "velocity":{
      "dataType":"number",
      "isMandatory": true,
      "description":"Device request processing speed per minute"
   }
  }
}
{
  "model":"abb.ability.device",
  "typeId":"Type.G",
  "version":"1.0.0",
  "baseTypes": ["Type.E@1.0.0"],
  "properties":{
    "deviceId":{
      "dataType":"string",
      "description":"Identifier of device."
   }
  }
}

Note that although it is allowed to change the BaseType for the sub type with a major version upgrade, doing so will lead to a change in the uniqueness group, which is forbidden.

Specifically, type.E is a "leader" of the unique group. A change to type.Q (below) will result in a switch from the unique group type.E to the "no group" type.

{
  "model":"abb.ability.device",
  "typeId":"Type.G",
  "version":"2.0.0",
  "baseTypes": ["Type.Q@1.0.0"],
  "properties":{
    "deviceId":{
      "dataType":"string",
      "description":"Identifier of device."
   }
  }
}

# Validation Rules

DCS validates all message properties as specified above and in the message body link. DCS validates that message body is in proper JSON format. DCS does not validate any message body properties. The message body is then passed to IM PUT /objects/{objectId}/models/{modelId} endpoint where remaining validation is performed

# Functionality

The requested object model is updated in the information model service, and in case of version gaps, the update is performed multiple times. After all updates are completed, the information model service version is equal to the request message version + 1.

The model notification C2D message Abb.Ability.ObjectModel.Updated should not be sent back. If requested, an acknowledgement C2D message is sent back to the directly connected device where it can also be propagated further if needed based on the target property.

NOTE

Any platform events related to this request that are generated by the IM are ignored by the DCS and are not propagated.

# Switching to Different Type Definition

It is possible using model.update message to switch existing object model to different Type Definition.
Switching to different Type Definition means:

  • Explicit upgrade/downgrade of type version, or
  • Explicit change to different type/subtype (in scope of the same unique group)

To switch between type definitions, Type Version has to be specified in request payload.
More info about unique group You can find here

# Handling of Type Definition Version

When the model is to be updated, the DCS uses the info model endpoint
PUT /objects/{objectId}/models/{modelId}.

Info model endpoint accepts a type with or without a version, and so does the DCS.

Whether with or without a version, the model.update payload body will include a type property of the info model.

When a type without a version is used in a model.update request payload, all processing is performed by the info model service alone.

For a discussion on how the info model service endpoint
PUT /objects/{objectId}/models/{modelId} function with and without a type version is specified, see Information Model Service Use Case for Type Versioning.

# Format of Returned Acknowledgment C2D Message

# Format of a Successful Acknowledgment

{
  "properties": {
    "msgType": "ack",
    "action": "model.update",
    "version": 2,
    "correlationId": "<correlation id>",
    "target": "<target matches the target in the corresponding action>",
    "timestamp": "<YYYY-MM-DDTHH:mm:ss.sssZ>"
  },
  "body": {
    "success": true,
    "code": "ok",
    "details": "",
    "objectId": "<objectId>",
    "model": "<model>",
    "version": <version>
  }
}

# Format of a Failing Acknowledgment

{
  "properties": {
    "msgType": "ack",
    "action": "model.update",
    "version": 2,
    "correlationId": "<correlation id>",
    "target": "<target matches the target in the corresponding action>",
    "timestamp": "<YYYY-MM-DDTHH:mm:ss.sssZ>"
  },
  "body": {
    "success": false,
    "code": "<error code>",
    "details": "<error details>"
  }
}

# Error Handling

When an error occurs the following processes log relevant information:

  • model.update message is completed inside the platform on Azure ServiceBus.
  • Error information is logged inside the Platform in Application Insights.
  • If a response can be delivered back to the device, acknowledgments are sent back to the device, if requested.
  • If response cannot be sent back to the device, the message is completed and only the error is logged.
Last updated: 9/6/2021, 1:25:50 PM
Feedback