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).
Error: No site found with the domain 's2.dicas-l.com.br' (Learn more)