---
# ----------------------------------------------------------------------------
# Service Commissioning File
# ----------------------------------------------------------------------------
# Copyright: Cybus GmbH
# Contact: support@cybus.io
# ----------------------------------------------------------------------------
# Sparkplug B Integration (Example)
# ----------------------------------------------------------------------------

description: >
  Service commissioning file for using Connectware as the central MQTT
  broker of a Sparkplug B infrastructure (Example)

metadata:
  name: Sparkplug B Integration
  provider: cybus
  homepage: https://www.cybus.io
  version: 1.0.0

parameters:
  groupId:
    description: Sparkplug group ID that the edge node belongs to
    type: string
    default: plant-hamburg

  edgeNodeId:
    description: Sparkplug edge node ID
    type: string
    default: press-line-01

  hostId:
    description: Sparkplug host ID of the host application
    type: string
    default: scada-primary

  edgeNodePassword:
    description: Password for the MQTT user of the edge node
    type: string

  hostAppPassword:
    description: Password for the MQTT user of the host application
    type: string

resources:
  # Permissions for one edge node: publish its own birth, death, and
  # data messages, subscribe to its command topics and the host STATE
  edgeNodeRole:
    type: Cybus::Role
    properties:
      permissions:
        - resource: !sub 'spBv1.0/${groupId}/NBIRTH/${edgeNodeId}'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/NDEATH/${edgeNodeId}'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/NDATA/${edgeNodeId}'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/DBIRTH/${edgeNodeId}/#'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/DDEATH/${edgeNodeId}/#'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/DDATA/${edgeNodeId}/#'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/NCMD/${edgeNodeId}'
          operation: read
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/DCMD/${edgeNodeId}/#'
          operation: read
          context: mqtt
        - resource: !sub 'spBv1.0/STATE/${hostId}'
          operation: read
          context: mqtt

  # MQTT user for the edge node. The username is prefixed with the
  # service ID, for example sparkplug.edge_press_line_01
  edge_press_line_01:
    type: Cybus::User
    properties:
      password: !ref edgeNodePassword
      roles:
        - !ref edgeNodeRole

  # Permissions for the host application: subscribe to the entire
  # Sparkplug namespace, publish commands and its own STATE message
  hostAppRole:
    type: Cybus::Role
    properties:
      permissions:
        - resource: spBv1.0/#
          operation: read
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/NCMD/#'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/${groupId}/DCMD/#'
          operation: write
          context: mqtt
        - resource: !sub 'spBv1.0/STATE/${hostId}'
          operation: write
          context: mqtt

  # MQTT user for the host application
  scada_primary:
    type: Cybus::User
    properties:
      password: !ref hostAppPassword
      roles:
        - !ref hostAppRole

  # Mirrors the Sparkplug namespace to internal topics for monitoring.
  # The protobuf payloads pass through unchanged. The STATE payload is
  # JSON, so a transform rule can process it.
  sparkplugMonitorMapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            topic: 'spBv1.0/#topic'
          publish:
            topic: 'sparkplug/monitor/#topic'
        - subscribe:
            topic: 'spBv1.0/STATE/+host'
          publish:
            topic: 'sparkplug/host-state/$host'
            retain: true
          rules:
            - transform:
                expression: >
                  {
                    "online": online,
                    "timestamp": timestamp
                  }
