---
# ----------------------------------------------------------------------------
# Service Commissioning File
# ----------------------------------------------------------------------------
# Copyright: Cybus GmbH
# Contact: support@cybus.io
# ----------------------------------------------------------------------------
# Connecting a Phoenix Contact PLCnext Controller (Example)
# ----------------------------------------------------------------------------

description: >
  Service commissioning file that reads variables from the built-in OPC UA
  server of a Phoenix Contact PLCnext controller with the OPC UA connector
  and maps them into an ISA-95 style MQTT topic hierarchy (Example)

metadata:
  name: PLCnext Controller Example
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  plcnextHost:
    description: Hostname or IP address of the PLCnext controller
    type: string
    default: 192.168.1.100

  plcnextPort:
    description: Port of the PLCnext OPC UA server
    type: integer
    default: 4840

  plcnextUsername:
    description: Username of a PLCnext user with OPC UA access
    type: string
    default: ''

  plcnextPassword:
    description: Password of the PLCnext user
    type: string
    default: ''

definitions:
  # ISA-95 style topic prefix: <enterprise>/<site>/<area>/<line>/<work-cell>
  MQTT_TOPIC_PREFIX: enterprise/hamburg/packaging/line-2/plc-01

resources:
  # Connection to the built-in OPC UA server (eUA server) of the controller.
  # With the default PLCnext security configuration, username and password
  # authentication requires an encrypted endpoint.
  plcnextConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      targetState: connected
      connection:
        host: !ref plcnextHost
        port: !ref plcnextPort
        username: !ref plcnextUsername
        password: !ref plcnextPassword
        options:
          messageSecurityMode: SignAndEncrypt
          securityPolicy: Aes128_Sha256_RsaOaep

  # The NodeIds below are project-specific. Replace the namespace index and
  # the Arp.Plc.Eclr/<program-instance>.<variable> paths with the values
  # from your own PLCnext Engineer project.

  # Conveyor running state (BOOL)
  conveyorRunning:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref plcnextConnection
      subscribe:
        nodeId: ns=5;s=Arp.Plc.Eclr/MainInstance.ConveyorRunning
        samplingInterval: 1000
        publishInterval: 1000

  # Actual motor speed (REAL)
  motorSpeed:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref plcnextConnection
      subscribe:
        nodeId: ns=5;s=Arp.Plc.Eclr/MainInstance.MotorSpeed
        samplingInterval: 250
        publishInterval: 1000

  # Actual motor current (REAL)
  motorCurrent:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref plcnextConnection
      subscribe:
        nodeId: ns=5;s=Arp.Plc.Eclr/MainInstance.MotorCurrent
        samplingInterval: 250
        publishInterval: 1000

  # Produced piece counter (UDINT)
  pieceCounter:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref plcnextConnection
      subscribe:
        nodeId: ns=5;s=Arp.Plc.Eclr/MainInstance.PieceCounter
        samplingInterval: 1000
        publishInterval: 1000

  mapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref conveyorRunning
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/conveyor/running'
        - subscribe:
            endpoint: !ref motorSpeed
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/motor/speed'
        - subscribe:
            endpoint: !ref motorCurrent
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/motor/current'
        - subscribe:
            endpoint: !ref pieceCounter
          publish:
            topic: !sub '${MQTT_TOPIC_PREFIX}/production/piece-counter'
