Configuração de Data Source Meta

Olá Sidney, obrigado pela atenção! Caso precise de mais informações, estou a disposição.
Atualmente estou contingenciando a situação com uma procedure SQL que apaga as entradas no banco para os id’s destes Data Points, desta forma o tamanho do banco permanece controlado.

Att,

O código abaixo deve servir:

// Segundo em milissegundos
var segundo = 1000;
// Minuto em milissegundos
var minuto = 60 * segundo;
// Hora em milissegundos
var hora = 60 * minuto;

// Obter os últimos 2 valores do nosso datapoint
var valores = new com.serotonin.mango.db.dao.PointValueDao();
valores = valores.getLatestPointValues(point.id, 2);

var tempo_menor = valores.get(1).time;
var tempo_maior = valores.get(0).time;
var tempo = tempo_maior - tempo_menor;

// Convertendo o tempo para horas
var hh = parseInt(tempo / hora);
hh = (hh > 9) ? hh : ("0" + hh);
// Obtendo o resto
tempo %= hora;

// Convertendo o tempo para minutos
var mm = parseInt(tempo / minuto);
mm = (mm > 9) ? mm : ("0" + mm);
// Obtendo o resto
tempo %= minuto;

// Convertendo o tempo para segundos
var ss = parseInt(tempo / segundo);
ss = (ss > 9) ? ss : ("0" + ss);

// Retornando o tempo em que permaneceu ligado
if (value == true) {
    return "<p class='queroCSS'>Ainda está ligado</p>";
} else {
    return "<p class='queroCSS'>" + hh + ":" + mm + ":" + ss + "</p>";
}

Amigo, talvez você tenha salvo a minha vida! Eu conheço pouco sobre utilização direta das classes do MangoDB, tens algum link ou referência de documentação compatível com a versão usada pelo ScadaBR? Seria bastante útil, a julgar apenas por essa parte com.serotonin.mango.db.dao.PointValueDao().getLatestPointValues(point.id, 2);

Agradeço muito a contribuição!
PS: testarei sua sugestão amanhã ao início das minhas atividades e darei o retorno.

Eu baixei a documentação aqui: https://sites.google.com/a/certi.org.br/certi_scadabr/desenvolvimento/api-scadabr/metodos-retornos-e-parametros (é o arquivo JavaDoc-API+Mango.rar lá no fim da página)

1 curtida

Celso, bom dia!
Muito obrigado pela sua ajuda, agora consigo prosseguir com o projeto!
PS: seu script funcionou, segue o resultado:
run

Que legal! Fico feliz que tenha dado certo.

Fala pessoal.

O código apresentado pelo Celso realiza o cálculo do horimetro e não salva no banco de dados, correto? Mas se eu precisar armazenar esse informação no banco para gerar um relatório, como poderia proceder a partir deste script?

Boa pergunta, vou pensar como (e se) é possível adaptar o código para isso. Se for, tentarei mostrar como fazer isso.

Tem um truque que eu uso para isso…

Crie um Data source Virtual, inclua um ponto virtual numero para armazenar seu horímetro, sem atualização automática, configurável, com valor inicial zero, por exemplo.

Depois, crie um Data Source META para rodar o script que foi proposto acima, só que atualizando o valor deste datasource virtual que foi criado para registrar o horímetro. Cadatre o padrão de atualização (Cron, horario especifico, a cada minuto, etc) e toda vez no intervalo ajustado o script será executado e o valor do datapoint virtual será atualizado.

Funciona legal este método. eu utilizo este método para horímetro de ensaios onde eu coleto dados e valido estes dados comparando com critperios maior, menor, igual, etc, e então se os critérios forem atendidos eu somo 1 minuto no horímetro, e executo de minuto em minuto, no meu caso.

Pra ficar mais avançado ainda, dá pra criar datapoints virtuais com os critérios numéricos que o script vai utilizar para tomar decisão e comparação, e assim têm-se um script automático configuravel em um painel, por exemplo.

Ok. Muito obrigado Celso. Existe algum outro caminho? tentei fazer usando o Data Source Meta, porém para a variável que recebe o cálculo do horimetro, precisa estar configurada nas propriedades de renderização como periodo → hh:mm:ss. Desta forma ocorre um erro de offeset de 9 horas, por exemplo, vamos supor que o resultado do horímetro 56 segundos, o resultado obtido é 09:00:56. Não sei como corrigir esse erro de offset. Já viram algo parecido?

Gulart muito obrigado pela resposta.

Tentei seguir a sua sugestão,para isso fui estudar aqui a questão da configuração do padrão Cron. Porém na hora que eu tento implementar no ScadaBR ,da erro da expressão. Para garantir a precisão do horímetro eu pensei em chamar o script a cada 30 segundos ( não sei se isso é viável tb, estou verificando), dai inseri a seguinte expressão Cron: 30 0 0 0 0 0. Porém da erro. Preciso informar mais alguma coisa? Minha expressão está incorreta?

Muito obrigado.

Consegui implementar a função Cron, acabei encontrando este link aqui do forum: http://forum.scadabr.com.br/t/uso-do-cron-pattern/138/3 . Porém a rotina não funcionou. O que eu fiz foi utilizar o script do Celso e no return eu apenas inseri uma variável com o tempo calculado. Estou usando a versão 1.0 do ScadaBR. Qual versão você usa?

Após certa dificuldade, consegui adaptar o código do script para servidor para o datapoint Meta. Para criar um horímetro que registre o tempo que um datapoint binário ficou ligado e vá salvando esse valor, o código abaixo deve funcionar:

// ID do datapoint binário
var id = 4;

// Segundo em milissegundos
var segundo = 1000;
// Minuto em milissegundos
var minuto = 60 * segundo;
// Hora em milissegundos
var hora = 60 * minuto;
// Dia em milissegundos
var dia = 24 * hora;

// Obter os últimos 2 valores do nosso datapoint
var valores = new com.serotonin.mango.db.dao.PointValueDao();
valores = valores.getLatestPointValues(id, 2);
var mais_antigo = valores.get(1);
var mais_recente = valores.get(0);

// Armazenar tempo em milissegundos numa variável
var tempo = 0;

if (String(mais_recente.value) == "true") {
	// Equipamento ligado, contar o tempo
    var tempo_atual = new Date().getTime(); // Usar o relógio do PC
	tempo = tempo_atual - mais_recente.time;
} else {
	// Equipamento desligado, pegar o tempo que ficou ligado
	tempo = mais_recente.time - mais_antigo.time;
}

// Converter o tempo de milissegundos para um formato legível

// Convertendo o tempo para dias
var dd = parseInt(tempo / hora);
// Obtendo o resto
tempo %= dia;

// Convertendo o tempo para horas
var hh = parseInt(tempo / hora);
hh = (hh > 9) ? hh : ("0" + hh);
// Obtendo o resto
tempo %= hora;

// Convertendo o tempo para minutos
var mm = parseInt(tempo / minuto);
mm = (mm > 9) ? mm : ("0" + mm);
// Obtendo o resto
tempo %= minuto;

// Convertendo o tempo para segundos
var ss = parseInt(tempo / segundo);
ss = (ss > 9) ? ss : ("0" + ss);

// Tudo feito, retornar o tempo em que permaneceu ligado
return dd + " dia(s) " + hh + "h " + mm + "min " + ss + "s";

A imagem abaixo mostra como eu configurei o datapoint Meta (note que é necessário alterar o ID do datapoint manualmente no código):

Por fim, tenho uma observação: como o Alan mencionou no primeiro post desse tópico, esse horímetro vai salvar um valor no banco de dados toda vez que o script for executado (o que pode gastar muito espaço caso você o configure para rodar com uma frequência alta). Isso talvez possa ser minimizado reduzindo o período dos dados que o ScadaBR mantém para o histórico desse datapoint, mas não tenho certeza porque não entendo praticamente nada de banco de dados.

1 curtida

Muito obrigado pela grande ajuda Celso!!

Vou implementar e dar uma olhada nesta questão do armazenamento no banco. Depois eu posto o resultado. Muito obrigado novamente!!

Olá Celso,

Para criar um horimetro realizei os passos dos post acima, no entanto esta aparecendo o seguinte alarme:


Criei o Data Source Meta com o nome HORIMETRO, em seguida criei um data point com o seu script, o id do datapoint binario é referente ao datapoint do data source TCP/IP que no meu caso é o número 4.

Ao rodar a aplicação surge o alarme citado acima.
No watch list não aparece nenhuma informação.

Alguma sugestão?

Parece que está dando um “estouro” no array porque o código está procurando os últimos 2 valores e não existe valor nenhum no histórico do ponto. Cuidado para não confundir o ID do data point com o Offset (endereço Modbus) do data point, são coisas diferentes.

Então, estou justamente fazendo isso…
Criei um Data Source Modbus IP, e os Data Points, desejo monitorar o tempo de acionamento do datapoint com o Offset 4, como faço para identificar o ID deste?

Existem várias formas de achar esse ID. Vou passar uma que eu acho que vai ser mais prática pra você. No seu data point Meta, vá até a opção Contexto do script e adicione o data point que você precisa descobrir o ID. Ele vai aparecer numa tabelinha na parte de baixo, e nessa tabela você vai ver um campo chamado “Var”. Nesse campo, vai aparecer um nome começado em p seguido de um número. Esse número que vem depois do p é o ID do data point.

Veja na imagem abaixo:

Achando%20o%20ID

Depois que você achou esse número, se não precisar, pode até remover o data point do “Contexto do Script”.

Showw, consegui identificar o ID e rodar o scripit, no entanto esta ocorrendo um atraso, perca e zeramento das informações de forma intermitente, por exemplo meu datapoint entra em funcionamento durante 5 minutos, teoricamento era para contabilizar esses 5 minutos (obs: a taxa de atualização do datasource esta a cada 1s), porém esse tempo as vezes é contabilizado e as vezes não, ou contabiliza e reseta após um liga/desliga do datapoint.

O que pode estar ocorrendo para perca dessas informações?

(Na propriedade de registro das informações dos datapoint o descarte de registro esta para a cada 1 ano.)

Boa tarde.

Então, o script que eu postei é um código bem simples. Basicamente ele parte do pressuposto de que o data point funciona de forma ininterrupta. O horímetro usa o histórico de valores do ScadaBR, que, além de salvar os valores do data point, salva o horário da alteração de valor. O script basicamente pega o horário em que houve a mudança entre os estados e calcula o tempo decorrido, chegando ao total de horas em que permaneceu ligado.

Se o seu data point liga e desliga várias vezes, esse horímetro não irá funcionar. Seria necessário adaptar o código para as suas necessidades, de modo que ele saiba exatamente quanto começar e terminar a contagem. Você também implementar um horímetro no Arduino ao invés do ScadaBR.

Infelizmente, estou com muito pouco tempo para interagir no fórum e não poderei lhe ajudar com essa implementação. De qualquer forma, desejo-lhe boa sorte.