Escrever scripts em Whistle

Este guia fornece orientações gerais sobre como escrever um script do Whistle para um analisador. Para mais informações sobre a sintaxe do Whistle e as funções disponíveis, consulte a referência do Whistle.

Produção de roteiros de apitos

Antes de começar a escrever um script do Whistle, recomendamos que você:

  1. Entenda o esquema das mensagens na classe de mensagem de origem a que o analisador se inscreve. Para evitar falhas de mapeamento e, consequentemente, mensagens na fila de mensagens inativas, o script do Whistle precisa mapear todas as mensagens recebidas. Se os esquemas de mensagens forem diferentes, o script do Whistle precisará processar essas diferenças.

    Conhecer o esquema da mensagem de origem ajuda a entender quais campos existem nas mensagens de origem e quais são os tipos de dados deles. Assim, você pode decidir como mapear os campos nas mensagens de origem para o esquema de tipo de destino. Também é importante entender a semântica dos dados para decidir quais partes da mensagem de origem devem ser mapeadas para atributos no esquema de destino.

    Por exemplo, saber a frequência da mudança no valor do atributo ajuda a decidir quais dados devem ser mapeados como metadados incorporados ou na nuvem. Consulte as seções sobre classes de mensagens de origem de modelagem e dados de modelagem.

  2. Entenda o esquema da versão do tipo definida para o analisador. O script Whistle no analisador mapeia mensagens de origem para o esquema de versão de tipo definido para o analisador. Para saber como criar um registro proto que atenda aos requisitos da versão do tipo, consulte a especificação do tipo. Em especial, observe o esquema do campo data e as associações de bucket de metadados. É importante observar se alguma associação de agrupamento de metadados está marcada como required: true. Se você planeja pesquisar instâncias de metadados por valor, anote os esquemas dos intervalos associados.

  3. Escreva o script do Whistle. O script do Whistle realiza a transformação real de origem para destino. A mensagem de origem é carregada em uma entrada chamada $root. Consulte a referência do Whistle para ter uma visão geral da linguagem e das funções disponíveis. Consulte também os outros guias nesta seção, como como vincular registros a instâncias de metadados.

Práticas recomendadas

Esta seção descreve as práticas recomendadas para escrever scripts do Whistle.

Realizar verificações nulas ao acessar propriedades de mensagens

É recomendável verificar se há um valor nulo ao acessar uma propriedade de mensagem sempre que houver a chance de ela não estar definida.

//Add metadata from source bucket if metadata.source attribute is present
if(isNotNil(input.metadata) and isNotNil(input.metadata.source)) then {
{
    var metadataArray[]: {
        bucketReference: {
            bucketName: "source";
            version: 1;
        };
            naturalKey: input.metadata.source;
        }
    }
}

Exemplos

As seções a seguir mostram alguns exemplos de operações básicas usando o Whistle.

Mapeamento simples do Whistle

Considere a seguinte mensagem de origem...

{
  "sensor": "rotation-speed-sensor",
  "machine": "m-234",
  "timestamp": "1687973092857",
  "value": 1200
}

E o seguinte script do Whistle:

package mde

[
    {
        tagName: $root.machine + " - " + $root.sensor;
        data: {
            numeric: $root.value;
        };
        timestamps: {
            eventTimestamp: $root.timestamp;
        }
    }
]

O analisador vai produzir esta saída de registro proto:

[
  {
    "tagName": "m-234-rotation-speed-sensor",
    "data": {
      "numeric": 1200
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

Mapeamento simples do Whistle usando funções

Considere a seguinte mensagem de origem:

{
  "sensor": "rotation-speed-sensor",
  "machine": "m-234",
  "timestamp": "1687973092857",
  "value": 1200
}

E o seguinte script do Whistle:

package mde

[
    {
        tagName: getTagName($root);
        data: getValue($root);
        timestamps: getTimestamp($root)
    }
]

def getTagName(input) {
    input.machine + "-" + input.sensor;
}

def getTimestamp(input) {
    eventTimestamp: input.timestamp;
}

def getValue(input) {
    numeric: input.value;
}

O analisador vai produzir esta saída de registro proto:

[
  {
    "tagName": "m-234-rotation-speed-sensor",
    "data": {
      "numeric": 1200
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

Emitir vários registros de proto de um analisador 1

Considere a seguinte mensagem de origem:

{
  "tag": "plc-34",
  "machine": "controller",
  "timestamp": "1687973092857",
  "values": [200, 499]
}

E o seguinte script do Whistle:

package mde

var valueLen: listLen($root.values);
var indexes: range(0, valueLen);

[
    getProtoRecords($root.values[], indexes[], $root)
]

def getProtoRecords(value, index, input) {
        tagName: input.machine + "-" + input.tag + "-" + index;
        data: {
            numeric: value;
        };
        timestamps: {
            eventTimestamp: input.timestamp;
        };
}

O analisador vai produzir esta saída de registro proto:

[
  {
    "tagName": "controller-plc-34-0",
    "data": {
      "value": 200.0
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  },
  {
    "tagName": "controller-plc-34-1",
    "data": {
      "value": 499.0
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

Emitir vários registros de proto de um analisador 2

Considere a seguinte mensagem de origem:

{
  "machine": "controller",
  "timestamp": "1687973092857",
  "sensors": [
    {
      "tag": "plc-34",
      "value": 200
    },
    {
      "tag": "plc-35",
      "value": 499
    }
  ]
}

E o seguinte script do Whistle:

package mde

[$$
    getProtoRecords($root.sensors[], $root)
]

def getProtoRecords(sensor, input) {
        tagName: input.machine + "-" + sensor.tag;
        data: {
            numeric: sensor.value;
        };
        timestamps: {
            eventTimestamp: input.timestamp;
        };
}

O analisador vai produzir esta saída de registro proto:

[
  {
    "tagName": "controller-plc-34",
    "timestamps": {
      "eventTimestamp": "1687973092857"
    },
    "data": {
      "numeric": 200
    }
  },
  {
    "tagName": "controller-plc-35",
    "timestamps": {
      "eventTimestamp": "1687973092857"
    },
    "data": {
      "numeric": 499
    }
  }
]