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ê:
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.
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
datae as associações de bucket de metadados. É importante observar se alguma associação de agrupamento de metadados está marcada comorequired: true. Se você planeja pesquisar instâncias de metadados por valor, anote os esquemas dos intervalos associados.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
}
}
]