Meta pontos são configurados criando um "contexto" de pontos existentes acessados pelo script quando executado. Estes pontos de contexto podem ser quaisquer pontos salvos no Scada-LTS, incluindo o ponto sendo editado. (O ponto corrente deve ser salvo—ou seja, não pode ser "novo"— antes de aparecer na lista de pontos de contexto.)
O Tipo de dado determina o tipo esperado de retorno para o script. O ponto tenta converter valor retornado do script para este tipo.
O Contexto do script define os pontos que estarão
disponíveis para o script quando for executado. Cada ponto
adicionado deve receber um nome de variável, chamado de Var,
que referencia o ponto no script. Estes nomes var devem ser nomes
válidos de variáveis de acordo com a linguagem ECMAScript:
devem iniciar com tanto uma letra ou com um sublinhado e não
devem conter espaços. Outras restrições podem
existir. Será exibida uma validação ou
exceções de execução do script se os nomes
das variáveis não estiverem definidos corretamente. Para
adicionar um ponto ao contexto, selecione o mesmo na lista e clique no
ícone . Para apagar um ponto
existente do contexto clique no ícone
associado ao ponto. Pontos que
não são necessários no script não devem ser
adicionados ao contexto, pois existe um consumo de memória na
preparação dos dados. Também é
possível que variáveis desnecessárias causem
execuções não intencionais do script. (Veja
"Execução do script" abaixo.) Entretanto, o
contrário também pode ser verdade: pode ser importante
incluir uma variável no contexto para que a
execução do script ocorra.
A área do Script é onde o script a ser executado deve ser programado. Scripts podem ser quaisquer ECMAScript válido que seria escrito dentro de uma função e function e sempre devem retornar um valor. Um script simples pode ser algo como:
return x.value;
... onde x é o nome de uma variável do script definida no contexto. O valor retornado do script é o valor atual do ponto cuja referência é 'x'. Funções matemáticas típicas podem ser executadas. Um exemplo mais complexo é apresentado abaixo:
return Math.sqrt(x.value * 3);
Este retorna a raiz quadrada do valor atual do ponto 'x' multiplicado por 3.(Nota: o objeto Math é definido por JavaScript. Favor consultar a documentação da ECMAScript para maiores informações.) Scripts mais complexos também podem ser escritos incluindo variáveis definidas logicamente, laços e estruturoas lógicas. Por exemplo:
var t = x.value + y.value; if (b.value) { for (var i=0; i<5; i++) { tmp += x.value - y.value; } } else { tmp = -tmp; } return tmp;
O script acima não tem intenção de calcular qualquer valor em particular, mas demonstrar o potencial de complexidade para escrita de scripts.
Adicionando ao contexto de ECMAScript, o Scada-LTS também define algumas funções globais úteis, incluindo max(), min(), avg() e sum(). (Estas funções são implementadas em um arquivo de scripts localizado em WEB-INF/scripts/scriptFunctions.js. Este arquivo pode ser alterado ou extendido conforme necessário para implementar funções globais particulares. O arquivo é carregardo na inicialização do Scada-LTS e, para instalar alterações deve-se reiniciar o Scada-LTS.) Para serem usados, basta que sejam chamados pelo script, por exemplo:
return max(x.value, y.value, z.value);
Isto retorna o valor máximo dos valores atuais de 'x', 'y' e 'z'. Qualquer número de parâmetros pode ser passasso a qualquer uma dessas funções globais.
Após a escrita do script, clique no ícone para que seja executado e tentar calcular o
resultado.
O timestamp do valor mais recente está disponível para o script. Os campos abaixo podem ser usados:
Para explicitamente definir o valor de um timestamp, defina a variável de contexto TIMESTAMP antes da declaração do retorno. O valor para definir essa variável deve ser em milisegundos a partir do valor de referência: 00:00:00 UTC em 01/01/1970 (ou 1970-01-01T00:00:00Z ISO 8601). Não deve ser uma data nativa. Por exemplo:
TIMESTAMP = new Date().getTime(); return p.value + 1;
A variável do script var que representa um ponto no script é, na realidade, um 'objeto' na terminologia JavaScript. Um objeto é um recipiente de valores e funções que pode ser referenciado pelo nome de suas propriedades. Para obter uma descrição das propriedades disponíveis para utilização em variáveis de script, use a propriedade help, por exemplo: use in a script var, use the help property, e.g.:
return x.help;
Este script funciona melhor se o tipo de dados é definido como alfanumérico, mas isso não é necessário. A propriedade help é idêntica à função toString(), que está disponível em todos os objetos de contexto e não apenas em variáveis de script.
A propriedade valor representa o valor atual do ponto. O tipo JavaScript do valor é análogo ao tipo definido no Scada-LTS: Binário se torna boolean, Numérico se torna float, Multi-estado se torna integer e Alnumérico se torna string.
Cada variável de script também implementa quatro funções. Os objetos retornado por essas funções dependem do tipo de dado que a variável representa. A propriedade help pode ser usada para obter uma descrição das propriedades do objeto retornado. Para o parâmetro "periodType" em todas as funções abaixo, as seguintes variáveis globais podem ser usadas: SECOND, MINUTE, HOUR, DAY, WEEK, MONTH e YEAR.
A função ago() retorna o valor que o ponto teve algum tempo atrás. Por exemplo, a chamada "x.ago(HOUR, 3)" retorna o valor do ponto exatamente 3 horas atrás.
A função past() returna um objeto que contém estatísticas sobre um período informado, que inicia no valor passado e termina agora. Veja abaixo uma descrição dos vários objetos estatísticos.
As funções prev() e previous() são idênticas; a última é fornecida por sua plenitude lingüística. As funções retornam o mesmo objeto estatístico fornecido por past(), mas em um lapso de tempo diferente. Os tempos de início e fim são quantificados para que correspondam ao período em questão. Por exemplo, se o tipo do período for HOURLY, o período for 1 e a função é executada às 18h05, o lapso de tempo que será usado inicia as 17h00 (inclusive) e termina as 18h00 (exclusive). Se o período for 3, o lapso de tempo seria das 15h00 às 18h00. De maneira similar, MONTH inicia à meia noite do primeiro dia do mês anterior e termina às 23h59:59 do último dia do mês anterior (quando o período for 1). Outros tipos de período funcionam da mesma maneira. Um período do tipo WEEK inicia à meia noite de Segunda-feira em concordância com padrões ISO.
Objetos estatísticos são retornados das funções past(), prev() e previous(). (Veja "Objetos de contexto" acima.) As propriedades do objeto retornado dependem do tipo de dados do ponto a partir do foi gerado. Valores de tempo em objetos são armazenados como integers, mas representam o número de milisegundos a partir de meia noite de 01/01/1970.
O objeto AnalogStatistics é retornado por pontos Numéricos e contém as seguintes propriedades:
Por exemplo, o script abaixo retorna o valor mínimo de 'n' na última hora:
return n.past(HOUR).minimum;
O objeto StartsAndRuntimeList é retornado por pontos Binários e Multi-estados e contém as seguintes propriedades:
Para acessar um objeto StartAndRuntime específico na lista, deve ser utilizada a função get(). Por exemplo, o script a seguir retorna a proporção do tempo que 'b' esteve no estado 'false' ao longo dos dois meses anteriores.
return b.past(MONTH, 2).get(false).proportion;
O objeto ValueChangeCounter é retornado por pontos Alfanuméricos. Contém apenas a propriedade changes, que informa o número de vezes que o valor do ponto foi alterado ao longo do período. Por exemplo, o script a seguir retorna o número de vezes que o valor de 'a' mudou nos últimos 45 minutos.
return b.previous(MINUTE, 45);
Por conveniência, se uma variável de objeto de script for retornado por um script, seu valor atual será utilizado. Assim, o script abaixo retorna o valor atual de 'x':
return x;
Entretanto, este script irá retornar o valor da soma de 'x' e 'y':
return x + y;
... mas este sim:
return x.value + y.value;
Cada vez que um script de um ponto for executado, o resultado é atribuído ao ponto como um valor atualizado. Os momentos em que um script é executado podem ser controlados pelo valor Update event. A configuração "Context update" força a execução do script sempre que um ponto dentro de seu contexto é atualizado. A outra configuração chama a execução do script no tempo indicado.
A configuração Execution delay (atraso de execução) pode ser usada para prevenir execuções múltiplas e não solicitadas do script. Frequentemente, um contexto do script irá utilizar múltiplos pontos, mas —quando usando execução em "Context update"—por que a atualização em cada ponto chama a execução do script, a atualização de todos os pontos a cada, por exemplo, hora irá forçar a execução script tantas vezes quanto o número de pontos a cada hora. De maneira similar, para execuções baseados em tempos, o script pode ser executado pouco antes de seus pontos de contexto serem atualizados e oferecer resultados incorretos. O atraso na execução de um script pode trazer resultados mais próximos dos esperados. Quando usando execução em atualização de contexto, o script não será executado após uma atualização de contexto até que o tempo de atraso seja atingido e não exista nova atualização de contexto. Para execuções baseadas em tempo, o script será executado após a quantidade de segundos definda a partir do tempo definido.
A configuração Context change faz com que o script seja executado sempre que um ponto dentro de seu contexto for alterado.
O script abaixo calcula a média horária circulante dos pontos 'n1' e 'n2':
return avg(b1.past(HOUR).average, b2.past(HOUR).average);
Este script calcula o número diário de pulsos de um contador de pulsos incremental (quando executado no "início do dia"):
return pulse.value - pulse.ago(DAY);
Este próximo script não é muito útil, mas é interessante. Ele circula entre os valores 1, 2 e 3, mas apenas muda aleatóriamente 1 a cada 100 execuções.
var r = Math.random(); if (r > 0.01) return x.value; if (x.value == 3) return 1; return x.value + 1;
Este script retorna o valor da soma dos valores inteiros de dois pontos numéricos'r' e 't':
return parseInt(t.value) + parseInt(r.value);