De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Rogério Acquadro
Data de Publicação: 04 de Janeiro de 2006
Recentemente tive que desenvolver uma pequena aplicação, responsável por capturar dados de leituras de temperatura e umidade relativa de salas climatizadas e fazer um tratamento estatístico dos dados. O software responsável pela captura das leituras (que não foi escrito por mim, é proprietário) gera um arquivo CSV, com atualização de hora em hora, com todos os dados de todos os sensores.
A dificuldade estava em automatizar, de uma maneira prática e simples, a geração dos gráficos e estatísticas para os dados em questão. Decidi que usar uma interface web seria a melhor opção. Não requer nenhum software instalado no cliente (como seria o caso de usar essa ou aquela planilha de cálculo).
São, no total, três computadores envolvidos nesta solução, obviamente todos ligados em rede. O primeiro deles é um computador velho, sucateado, que faz apenas a leitura dos dados. Trata-se de um Pentium 200, rodando Windows 95 e com o software proprietário de captura dos dados. Este computador está ligado via RS232 aos sensores e é dessa maneira que são feitas as leituras dos dados.
O segundo é o servidor da aplicação. Sua função é acessar o computador de captura, ler os últimos dados, registrá-los em um banco de dados e abrigar a aplicação web.
O terceiro computador é o cliente, que necessita apenas de um navegador de Internet. A observação é que o cliente pode ter qualquer navegador de internet com qualquer sistema operacional.
Além do software proprietário que faz a captura dos dados, foram utilizados os seguintes softwares:
O primeiro passo é fazer a captura dos dados. Para isso, foi escrito um pequeno script ("captura"):
1 #!/bin/bash 2 3 cd /tmp 4 mount -t smbfs -o username=acervo,password=acervo //terminal/c /mnt/extra 5 mv /mnt/extra/dados/dado.csv /tmp 6 umount /mnt/extra 7 /opt/climatizacao/gera_sql /tmp/dados.csv | mysql climatizacao 8 rm /tmp/dados 9 rm /tmp/*.bak
Analizando linha a linha, começamos com a linha 4 que faz a conexão com o computador de aquisição de dados via samba. A linha 5 copia o arquivo de dados para o diretório temporário (ele na verdade move o arquivo. Assim, na próxima vez que o software for escrever novos dados, criará um novo arquivo, sem que aja a duplicação de dados). A linha 7 invoca o segundo script que trata os dados do arquivo CSV e insere dentro do MySQL.
O segundo passo é fazer o tratamento do arquivo CSV e injetar os dados no banco de dados. Isso é feito utilizando o segundo script ("gera_sql"), invocado na linha 7 do script "captura":
1 #!/bin/bash 2 3 dos2unix -a $1 4 sed -e s/\;//g $1 | sed -e 's|/| |' | sed -e 's|/| |' |\ awk {'print "insert into traineis values \ (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$8 "\"\, \""$9 "\"\, \""$10 "\"\, \""$11"\"); \n\ 5 insert into exterior values (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$12 "\"\, \""$13 "\"\, \""$14 "\"\, \""$15"\");\n\ 6 insert into climatizada values (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$16 "\"\, \""$17 "\"\, \""$18 "\"\, \""$19"\");\n\ 7 insert into sala_3 values (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$20 "\"\, \""$21 "\"\, \""$22 "\"\, \""$23"\");\n\ 8 insert into audiovisual values (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$24 "\"\, \""$25 "\"\, \""$26 "\"\, \""$27"\");\n\ 9 insert into armario values (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$28 "\"\, \""$29"\");\n\ 10 insert into arcondicionado values (\"\"\, \"20"$3"-" $1 "-"$2"\"\, \""$4 "\"\, \""$30 "\"\, \""$31 "\"\, \""$32 "\"\, \""$33 "\"\, \""$34"\");"'}
A linha 3 faz uma pequena conversão de formatos de arquivo texto (necessário dado o comando para quebra de linha ser diferente entre *NIX e Windows). A 4a. linha faz a separação dos dados (separados por vírgula). Mais do que isso, a 4a. linha faz ainda o tratamento da data (que é gerada do tipo dd/mm/aa e o SQL apenas reconhece aaaa-mm-dd). As linhas de 5 a 10 são as linhas de injeção de dados no SQL.
Injetados os dados no banco de dados, cabe ao aplicativo PHP fazer a leitura deles. Graças as funções estatísticas do MySQL, pode-se gerar rapidamente cálculos como média +- desvio padrão, máximos e mínimos, entre outros. A grande dificuldade está na geração do gráfico de umidade e temperatura.
Depois de muito pesquisar bibliotecas prontas para gerar gráficos em PHP (nenhuma me soou muito satisfatória), resolvi enfrentar o desafio de usar o GNUPlot (excelente ferramenta da qual já sou familiar há tempos) junto com o PHP.
Para isso, escrevi o programa graph.php, que passado o nome do sensor e as datas de início e fim, ele é capaz de gerar o gráfico de temperatura e umidade.
1 $sensor = $_GET['sensor']; 2 $limite1 = $_GET['limite1']; 3 $limite2 = $_GET['limite2']; 4 $size = $_GET['size']; 5 if (($limite1 != NULL) && ($limite2 != NULL)) 6 $limite = "where data >= '$limite1' and data <= '$limite2'"; 7 $filename = round(time() / 10 * rand(1,10)); 8 $filename = "/tmp/".$filename; 9 if ($size == "small") 10 $term = "png size 640,480"; 11 if ($size == "big") 12 $term = "png size 950,712"; 13 $query = "select data, hora, temp, ur from $sensor $limite order by data, hora"; 14 $result = mysql_query($query); 15 $rows = mysql_num_rows($result); 16 if ($rows > 720) 17 $passo = 10; 18 elseif ($rows > 360) 19 $passo = 5; 20 else 21 $passo = 1; 22 for ($i = $rows - 1; $i >= 0; $i = $i - $passo) 23 { 24 25 $x = mysql_result($result, $i, "data") . "-" . mysql_result($result, $i, "hora"); 26 $y1 = mysql_result($result, $i, "temp"); 27 $y2 = mysql_result($result, $i, "ur"); 28 $command = "echo $x $y1 $y2 >> $filename"; 29 exec ($command); 30 } 31 $command = "echo \"set ylabel \\\"Temperatura (celsius)\\\"; set y2label \\\"Umidade Relativa (%)\\\"; set xlabel \\\"Data\\\"; set grid; set y2tics; set term $term; set xdata time; set timefmt \\\"%Y-%m-%d-%H:%M\\\"; plot \\\"$filename\\\" using 1:2 axis x1y1 title \\\"Temp\\\" with lines, \\\"$filename\\\" using 1:3 axis x1y2 title \\\"UR\\\" with lines \" | gnuplot"; 32 header("Content-type: image/png"); 33 passthru($command); 34 $command = "rm $filename"; 35 exec ($command);
As linhas de 1 a 4 fazem a leitura dos parâmetros. As linhas 7 e 8 geram um nome aleatório para o arquivo temporário de dados que será lido pelo GNUPLot. As linhas de 9 a 12 definem o tamanho do gráfico (em pixels). As linhas 13 e 14 fazem a conexão com o banco de dados. As linhas 16 a 21 fazem a triagem dos dados (dependendo do período que se deseja, o banco de dados possui mais de 3.000 pontos, o que deixava o programa um pouco lento. Como não havia necessidade de tantos pontos, o período foi dividido para que ficasse mais de acordo com o propósito do gráfico). As linhas de 22 a 30 fazem a leitura dos dados e a escrita deles no arquivo temporário. A linha 31 é o comando em sintaxe GNUPlot para que faça a formatação do gráfico, leitura dos dados e desenho dos pontos. A linha 32 envia ao navegador a informação que a saída será um arquivo PNG. A linha 33 faz a geração do gráfico (executa os comandos da linha 31). As linhas 34 e 35 apagam o arquivo texto temporário.
Para chamar o "grap.php", basta colocar em um arquivo HTML a chamada como se fosse um arquivo gráfico:
<img src=\"graph.php?sensor=$sensor&limite1=$limite1&limite2=$limite2&size=small\" title=\"Gráfico de temperatura e umidade relativa para $sensor\" border=\"0\">
O resultado deste software é brilhante. Um gráfico gerado em segundos, extremamente leve (o gráfico mais pesado que gerei não passa de 15 kbytes).
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários