Acesso direto ao conteúdo
Logotipo Dicas-L, por Ricardo Burile

Busca

Visite também: Segurança Linux ·  UnderLinux ·  VivaOLinux ·  LinuxSecurity ·  NoticiasLinux ·  BR-Linux ·  SoftwareLivre.org ·  [mais]   
 

Você está aqui: Home  → Arquivo Dicas-L

 

Aprenda inglês de uma vez por todas

Assine a Lista Dicas-L

Receba diariamente por email as dicas
de informática publicadas neste site
Para se descadastrar, clique aqui.

Gráficos usando GNUPlot e PHP

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).

Infraestrutura

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.

Softwares utilizados

Além do software proprietário que faz a captura dos dados, foram utilizados os seguintes softwares:

  • Pequenos scripts em shell script para fazer o tratamento dos dados e a injeção no banco de dados;
  • Samba para fazer a comunicação e transferência dos dados entre a o computador de aquisição de dados e o servidor;
  • MySQL para armazenagem dos dados;
  • PHP para desenvolvimento da aplicação;
  • GNUPlot para geração dos gráficos;
  • Um navegador de Internet no computador cliente.

Passo a Passo

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).

Veja a relação completa dos artigos de Rogério Acquadro

Formato PDF
Newsfeed RSS
Formato para impressão
PDF RSS Imprimir

Referências Adicionais

Referências adicionais sobre os assuntos abordados neste site podem ser encontradas em nossa Bibliografia.

Avalie esta dica

  • Currently 2.99/5
  • 1
  • 2
  • 3
  • 4
  • 5

Avaliação: 3.0 /5 (1342 votos)

Opinião dos Leitores

Manoel Matos de Souza
10 Abr 2012, 14:22
Estou a procura de dados estatísticos de quantos e quais os sites que vendem óculos on-line(site de óticas. Não tenho conhecimento técnico de informática. Esses dados serviram apenas para embasar um (Plano de Negócios) que estou elaborando.

No aguardo.

Agradeço antecipadamente.

Manoel Matos
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script
Treinamentos, Consultorias e Soluçoes em TI. Baseados em softwares livres e padrões abertos para ambientes de missão crítica

Submarino.com.br

Programando o Android