description: >
    Machine connectivity and data mapping

metadata:
  name: ModBus Machine Connectivity
  icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
  provider: cybus
  homepage: https://www.cybus.io
  version: 0.0.1

parameters:
  modbus_connection_ip:
    type: string
    default: 172.17.0.1

  modbus_connection_port:
    type: integer
    default: 10502

resources:

  # Modbus simulator service for this example
  machineSimulator:
    type: Cybus::Container
    properties:
      image: registry.cybus.io/cybus-testing/modbus-machine-simulator:0.0.1
      ports:
          - !sub '${modbus_connection_port}:10502/tcp'

  modbusConnection:
    type: Cybus::Connection
    properties:
      protocol: Modbus
      targetState: connected
      connection:
        host: !ref modbus_connection_ip
        port: !ref modbus_connection_port

  powerLevel:
    type: Cybus::Endpoint
    properties:
      protocol: Modbus
      connection: !ref modbusConnection
      subscribe:
        fc: 3
        length: 2
        interval: 1000
        address: 0
        dataType: floatBE

  mapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref powerLevel
          publish:
            topic: !sub "${Cybus::MqttRoot}/power-level"
        - subscribe:
            endpoint: !ref powerLevel
          rules:
            - transform:
                expression: |
                  (
                      $stateMap := [
                          {
                              "lower": 0,
                              "upper": 0,
                              "state": "OFF"
                          },
                          {
                              "lower": 1,
                              "upper": 10,
                              "state": "IDLE"
                          },
                          {
                              "lower": 11,
                              "upper": 40,
                              "state": "JOG"
                          },
                          {
                              "lower": 41,
                              "upper": 100,
                              "state": "RUNNING"
                          }
                      ];
                      $findState := function($stateRaw) {
                          (
                          $result := $filter($stateMap, function($v) {
                              ($stateRaw >= $v.lower and $stateRaw <= $v.upper)
                          });
                          $result ? $result[0].state : "ERROR"
                          )
                      };
                      {
                          "powerlevel": value,
                          "state": $findState(value),
                          "timestamp": timestamp
                      }
                  )
          publish:
            topic: !sub "${Cybus::MqttRoot}/machine-state"
