asyncapi: '2.0.0'
id: 'http://www.siemens.com/industry/edge/databus/profinet_io_connector'
info:
  title: 'Siemens Industrial Edge Databus, extensions for PROFINET IO Connector'
  version: '1.2.0'

servers:
  databusLocalNew:
    url: mqtt://ie-databus:1883
    protocol: mqtt
    description: The Industrial Edge Databus broker. New DNS name since Edge V1.1

  databusLocalDeprecated:
    url: mqtt://ie_databus:1883
    protocol: mqtt
    description: >
      The Industrial Edge Databus broker in V1.0.  Use 'databusLocalNew' for Edge versions >= 1.1.
      Support for the DNS name "ie_databus' will be removed in the next major version.

defaultContentType: application/json

channels:
  # PROFINET write DataRecord request
  # added in version 1.2
  'ie/d/j/{msgStructureScheme}/{msgStructureSchemeMajorVersion}/{providerAppInstanceId}/rcd/w{dpConnectionNamePath}req':
    description: 'Write PROFINET Record Request JSON payload format'
    parameters:
      msgStructureScheme:
        $ref: '#/components/parameters/msgStructureScheme'
      msgStructureSchemeMajorVersion:
        $ref: '#/components/parameters/msgStructureSchemeMajorVersion'
      providerAppInstanceId:
        $ref: '#/components/parameters/providerAppInstanceId' 
      dpConnectionNamePath:
        $ref: '#/components/parameters/dpConnectionNamePath' 
    publish:
      operationId: pubPnWriteDataRecordRequest
      message:
        $ref: '#/components/messages/pubPnWriteDataRecordRequestMsg'
      bindings:
        mqtt:
          qos: 0
          retain: false

  # PROFINET write DataRecord response
  # added in version 1.2
  'ie/d/j/{msgStructureScheme}/{msgStructureSchemeMajorVersion}/{providerAppInstanceId}/rcd/w{dpConnectionNamePath}rsp':
    description: 'Write PROFINET Record Response JSON payload format'
    parameters:
      msgStructureScheme:
        $ref: '#/components/parameters/msgStructureScheme'
      msgStructureSchemeMajorVersion:
        $ref: '#/components/parameters/msgStructureSchemeMajorVersion'
      providerAppInstanceId:
        $ref: '#/components/parameters/providerAppInstanceId' 
      dpConnectionNamePath:
        $ref: '#/components/parameters/dpConnectionNamePath' 
    subscribe:
      operationId: subPnWriteDataRecordResponse
      message:
        $ref: '#/components/messages/subPnWriteDataRecordResponseMsg'
      bindings:
        mqtt:
          qos: 0
          retain: false

  # PROFINET read DataRecord request
  # added in version 1.2
  'ie/d/j/{msgStructureScheme}/{msgStructureSchemeMajorVersion}/{providerAppInstanceId}/rcd/r{dpConnectionNamePath}req':
    description: 'Read PROFINET Record Request JSON payload format'
    parameters:
      msgStructureScheme:
        $ref: '#/components/parameters/msgStructureScheme'
      msgStructureSchemeMajorVersion:
        $ref: '#/components/parameters/msgStructureSchemeMajorVersion'
      providerAppInstanceId:
        $ref: '#/components/parameters/providerAppInstanceId' 
      dpConnectionNamePath:
        $ref: '#/components/parameters/dpConnectionNamePath' 
    publish:
      operationId: pubPnReadDataRecordRequest
      message:
        $ref: '#/components/messages/pubPnReadDataRecordRequestMsg'
      bindings:
        mqtt:
          qos: 0
          retain: false

  # PROFINET read DataRecord response
  # added in version 1.2
  'ie/d/j/{msgStructureScheme}/{msgStructureSchemeMajorVersion}/{providerAppInstanceId}/rcd/r{dpConnectionNamePath}rsp':
    description: 'Read PROFINET Record Response JSON payload format'
    parameters:
      msgStructureScheme:
        $ref: '#/components/parameters/msgStructureScheme'
      msgStructureSchemeMajorVersion:
        $ref: '#/components/parameters/msgStructureSchemeMajorVersion'
      providerAppInstanceId:
        $ref: '#/components/parameters/providerAppInstanceId' 
      dpConnectionNamePath:
        $ref: '#/components/parameters/dpConnectionNamePath' 
    subscribe:
      operationId: subPnReadDataRecordsResponse
      message:
        $ref: '#/components/messages/subPnReadDataRecordsResponseMsg'
      bindings:
        mqtt:
          qos: 0
          retain: false

components:
  parameters:
    providerAppInstanceId:
      description: 'The instance ID of an Edge App.'
      schema:
        type: string
        examples:
          - "s7c1"

    msgStructureSchemeMajorVersion:
      description: 'Major version of the SIMATIC payload schema version, prefixed by "v".'
      schema:
        $ref: '#/components/schemas/msgStructureSchemeMajorVersion'

    msgStructureScheme:
      description: 'Name of the JSON schema. Has to be "simatic" for the SIMATIC schema.'
      schema:
        $ref: '#/components/schemas/msgStructureScheme'

    dpConnectionNamePath:
      description: "The connection name of a connector, including the leading '/'."
      schema:
        type: string
        pattern: '^(/[^/]+)?$' # can be empty, but when non-empty must start with '/' and not contain '/'
        examples:
          - "/PLC_1"

  messages:
    pubPnWriteDataRecordRequestMsg:
      name: pubPnWriteDataRecordRequestMsg
      contentType: application/json
      payload:
        $ref: "#/components/schemas/pubPnWriteDataRecordRequestPayload"

    subPnWriteDataRecordResponseMsg:
      name: subPnWriteDataRecordResponseMsg
      contentType: application/json
      payload:
        $ref: "#/components/schemas/subPnWriteDataRecordResponsePayload"

    pubPnReadDataRecordRequestMsg:
      name: pubPnReadDataRecordRequestMsg
      contentType: application/json
      payload:
        $ref: "#/components/schemas/pubPnReadDataRecordRequestPayload"

    subPnReadDataRecordsResponseMsg:
      name: subPnReadDataRecordsResponseMsg
      contentType: application/json
      payload:
        $ref: "#/components/schemas/subPnReadDataRecordResponsePayload"


  schemas:
    sequenceNumber:
      description: >
        Sequence number. The number will monotonically increase until it
        reaches its maximum and then wrap around to 0. It can be used to
        detect missed messages.
        When a service restarts, this value can also start again at 0,
        it will not be persisted between restarts.
      type: integer
      minimum: 0
      maximum: 4294967295

    automationTimestamp:
      type: string
      pattern: '^(160[1-9]|16[1-9][0-9]|1[7-9][0-9]{2}|[2-9][0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.[0-9]{1,7})?Z$'
      #format: "date"  # the 'date' format doesn't fully match our needs with the high resolution!
      description: >
        High resolution ISO8601 based timestamp in UTC time zone.
        The resolution is 100 ns and the range is from 1601-01-01 to 9999-12-31.
        We expect the format yyyy-MM-ddTHH:MM:SS.sssssssZ where the
        decimal part can be omitted or otherwise must contain between 1 and 7 digits.
        The range and resolution comes from the OPC UA binary data type 'DateTime' as
        defined in part 6.
        Leap seconds (seconds=60) are not supported.
      examples:
        - "2020-11-23T16:35:41.1234567Z"
        - "1601-11-23T16:35:41.123Z"
        - "9999-11-23T16:35:41.1Z"
        - "2039-11-23T16:35:41Z"

    msgStructureScheme:
      description: 'The name of the JSON schema. Can only be "simatic"'
      type: string
      const: 'simatic'
      examples:
        - "simatic"
        
    msgStructureSchemeMajorVersion: # 'msgStructureSchemeVersion' in Wiki spec
      description: 'The version of the JSON schema. Can only be "v1"'
      type: string
      const: 'v1'
      examples:
        - "v1"

    pubPnWriteDataRecordRequestPayload:
      type: object
      additionalProperties: false
      required:
        - reqs
      properties:
        seq:
          $ref: "#/components/schemas/sequenceNumber"

        reqs:
          type: array
          items:
            $ref: "#/components/schemas/pubPnWriteDataRecordRequestItem"

    pubPnWriteDataRecordRequestItem:
      type: object
      additionalProperties: false
      required:
        - laddr
        - index
        - val
      properties:
        laddr:
          $ref: "#/components/schemas/profinetSubmoduleLaddr"

        index:
          $ref: "#/components/schemas/profinetSubmoduleIndex"

        val:
          $ref: "#/components/schemas/profinetRecordData"

    subPnWriteDataRecordResponsePayload:
      type: object
      additionalProperties: false
      required:
        - rsps
      properties:
        seq:
          $ref: "#/components/schemas/sequenceNumber"

        rsps:
          type: array
          items:
            $ref: "#/components/schemas/subPnWriteDataRecordResponseItem"

    subPnWriteDataRecordResponseItem:
      type: object
      additionalProperties: false
      required:
        - status
        - ts
      properties:
        laddr:
          $ref: "#/components/schemas/profinetSubmoduleLaddr"

        index:
          $ref: "#/components/schemas/profinetSubmoduleIndex"

        status:
          $ref: "#/components/schemas/profinetResponseStatus"

        errorDescription:
          $ref: "#/components/schemas/profinetResponseErrorDescription"

        ts:
          description: >
            Timestamp when the response arrived at the Connector App.
          $ref: "#/components/schemas/automationTimestamp"

    pubPnReadDataRecordRequestPayload:
      type: object
      additionalProperties: false
      required:
        - reqs
      properties:
        seq:
          $ref: "#/components/schemas/sequenceNumber"

        reqs:
          type: array
          items:
            $ref: "#/components/schemas/pubPnReadDataRecordRequestItem"

    pubPnReadDataRecordRequestItem:
      type: object
      additionalProperties: false
      required:
        - laddr
        - index
      properties:
        laddr:
          $ref: "#/components/schemas/profinetSubmoduleLaddr"

        index:
          $ref: "#/components/schemas/profinetSubmoduleIndex"

    subPnReadDataRecordResponsePayload:
      type: object
      additionalProperties: false
      required:
        - rsps
      properties:
        seq:
          $ref: "#/components/schemas/sequenceNumber"

        rsps:
          type: array
          items:
            $ref: "#/components/schemas/subPnReadDataRecordResponseItem"

    subPnReadDataRecordResponseItem:
      type: object
      additionalProperties: false
      required:
        - status
        - ts
      properties:
        laddr:
          $ref: "#/components/schemas/profinetSubmoduleLaddr"

        index:
          $ref: "#/components/schemas/profinetSubmoduleIndex"

        val:
          $ref: "#/components/schemas/profinetRecordData"

        status:
          $ref: "#/components/schemas/profinetResponseStatus"

        errorDescription:
          $ref: "#/components/schemas/profinetResponseErrorDescription"

        ts:
          description: >
            Timestamp when the response arrived at the Connector App.
          $ref: "#/components/schemas/automationTimestamp"

    profinetRecordData:
      type: array
      items:
        type: integer
        minimum: 0
        maximum: 255

    profinetSubmoduleLaddr:
      type: integer
      minimum: 0
      maximum: 4294967295

    profinetSubmoduleIndex:
      type: integer
      minimum: 0
      maximum: 4294967295

    profinetResponseStatus:
      type: integer
      minimum: 0
      maximum: 4294967295
      description: >
        Describes the status of the operation.
        '0' means ok, every other value signals an error.
        Refer to 'profinetResponseErrorDescription' for a description of the error

    profinetResponseErrorDescription:
      type: string
      description: >
        Describes the status of the operation in human readable form.
        Is only present when 'profinetResponseStatus'!=0 that means when
        an error has occurred