O sistema de armazenamento é responsável por receber a informação via
socket, fazer o pré-tratamento de compressão decidindo se a informação deve ser ou
não armazenada na tabela de valores do banco de dados com compressão, alterando
a tabela de snapshot que mantém sempre o valor mais recente para cada tag. Além
disso, esse subsistema é também responsável por armazenar em outra tabela os
valores recebidos sem compressão para testes comparativos de armazenamento.
Para a leitura dos dados na placa de rede é utilizado um server socket. O
socket de usuário cria um canal de comunicação que recebe os dados de outra
aplicação, enquanto um server socket se mantém ativo durante todo o funcionamento
da aplicação aguardando novas mensagens do cliente.
Para melhor entendimento do processo de análise do dado recebido é
necessário detalhar o funcionamento da base de dados criada.
Todo banco de
dados criado se baseia na modelagem apresentada na figura 16 que apresenta quatro
tabelas atemporais:
Node, que armazena as informações da interface; Datasource,
que armazena informações dos pontos de coleta que estão enviando dados para a
interface;
Tag, que armazena as informações de cada instrumento presente naquela
interface e a tabelasnapshot, que armazena sempre o último estado para o conjunto
de tags.
Além dessas, existe a tabela temporal
valores que armazena todo o histórico
para as tags existentes no momento em que as mudanças acontecerem, essas tabelas
são apresentadas na figura 29.
A tabela
Node possui um identificador idNode como chave primária, um
atributo
Nome que é um vetor de quarenta e cinco caracteres que armazena
o nome do nó, e um atributo
descrição que armazena, em 255 caracteres,
as informações do nó existente.
Na tabela
Datasource estão identificados os
atributos
idESTACAO_METEO como chave primária; o atributo NOME_ESTACAO
que armazena o nome da fonte da coleta de dados; o atributo
FABRICANTE que
identifica o fabricante da estação de coleta; o
MODELO que é um atributo de
identificação da estação utilizada e uma chave estrangeira
NODE_idNODE que
mostra de qual interface esta fonte de dados faz parte.
A tabelaTag possui algumas informações referentes aos instrumentos medidos
pela fonte de dados, no caso, a estação meteorológica NomadII. Para a indentificação
das tags existe uma coluna
idTAG que representa o código identificador para cada
tag. O atributo
NOME_TAG é uma string que identifica o nome da tag, sendo que
Figura 29: Visão das tabelas do banco de dados criado
Fonte: Próprio autor
esse nome deve ser único, já que algumas ações são realizadas pelo nome da tag.
O atributo
DESCRICAO é uma string de 255 caracteres que armazena informações
extras sobre os pontos coletados. O atributoDESVIO armazena o valor de referência
para os cálculos da altura do paralelogramo no algoritmo de compressão. O Atributo
TEMP_MAX possui o tempo máximo de espera por um valor, também utilizado no
algoritmo de compressão, a tag ainda possui uma chave estrangeira que define de
qual fonte de dados esta tag é coletada.
As tabelas
snapshot e valores possuem os mesmos atributos, mas têm
funções diferentes.
Respectivamente, elas armazenam o último valor coletado e
todos os valores coletados.
A aplicação de armazenamento atualiza a tabela
snapshot a cada coleta e armazena um novo valor após a compressão na tabela
valores. Os atributos dessas tabelas são:
IdVALOR, que identifica o valor atualizado
ou armazenado; o atributo
VALOR que armazena o valor lido da estação de
coleta; o atributo
DATAHORA armazena o carimbo de tempo colhido e duas
chaves estrangeiras
TAG_idTAG e TAG_ESTACAO_METEO_idESTACAO_METEO
que identificam a tag a quem pertence aqueles valores (já que existem várias tags) e
de qual estação meteorológica é a determinada tag.
Conhecendo detalhadamente a base de dados e suas informações relevantes,
a string recebida pelo subsistema de armazenamento é devidamente fragmentada
de forma que seja possível extrair cada informação sobre a tag em questão. Cada
informação recebida é armazenada em uma estrutura instanciada da classe Valor.
A partir dos valores recebidos é possível buscar e recuperar no banco de dados
as informações referentes à tag. Com o armazenamento do novo valor no objeto
ValorRecente do Tipo Valor e as informações armazenadas em um objeto Tes do
tipotag, é possível buscar o último valor gravado no banco, UltimoGravado, e o valor
atual na tabela desnapshot, ValorAtual. Estes três objetos são enviados junto com
o desvio estipulado e o tempo máximo para compressão como parâmetro do método
TesteParaleogramo() que é a rotina de teste para validar a gravação do valor atual.
O valor da tag é referenciado como valor recente, ou seja, o valor que fora
lido pela estação de coleta, e que passará por uma avaliação acerca da necessidade
de seu armazenamento. Essa avaliação é o teste do paralelogramo, que, além do
ValorRecente, ainda recebe como parâmetros o último valor associado a essa tag
gravado no banco de dados (referenciado como úultimo valor gravado), o valor atual
da tabela de snapshot (referenciado como valor atual), o valor de desvio considerado
pelo algoritmo e o tempo máximo que o algoritmo tolera não gravar uma amostra
(referenciado como tempo máximo).
O teste do paralelogramo (como já apresentado) cria um paralegramo a partir
dos valores e tempos das amostras testadas e do desvio estipulado. Caso o valor
atual esteja fora do paralelogramo, ele é armazenado no banco de dados se tornando
o último valor gravado e o valor recebido se torna o atual, sendo gravado no snapshot.
Para montar o paralelogramo e saber se o valor atual está dentro da faixa de
valores esperada, foi utilizado o cálculo do coeficiente angular da reta entre o último
valor gravado (Ug) e o último valor recebido (Vr), considerando os desvios para mais
e para menos.
Esse coeficiente angular é igual à tangente do ângulo formado pela retaUgVr
e o eixo do tempo, que é igual a razão entre o cateto oposto (Vr-Ug) e o cateto
adjacente (Tr-Tg). Na figura 30 pode-se observar os triângulos retângulos formados
pela reta passando pelos pontosUg, valor esperado (Ve) e Vr junto com os pontos no
tempo, tempo gravado (Tg), tempo atual (Ta) e tempo recebido (Tr). Com os tempos
relacionados a cada valor é possível encontrar oVe e saber se o valor atual (Va) está
dentro da faixa de valores esperados, como apresentado na figura 31.
Calculando o coeficiente angular da reta, tem-se
T g(α) =V r−Ug
Tr− T g,
(1)
Como
Ve faz parte da reta entre Vr e Ug, o coeficiente angular é o mesmo.
Conhecendo o coeficiente angular e o tempo atual é possível calcularVe como segue:
T g(α) =Ve−Ug
Ta− T g,
(2)
Ve−Ug
Ta− T g
=
V r−Ug
Tr− T g,
(3)
Ve= ((V r −U g)x(Ta − T g)
Tr− T g
) +U g.
(4)
Figura 30: Ângulos formados por tags armazenadas
Fonte: Próprio autor
A partir deVe e do valor de desvio é possível saber se Va está no paralelogramo
verificando se
Va é maior que Ve mais o valor de desvio ou se Va é menor que Ve
menos o valor de desvio. Se o valor deVa estiver dentro do paralelogramo, esse valor
não deve ser armazenado no banco de dados. O valor deVa será armazenado apenas
se ele estiver fora do paralelogramo, ou se a diferença entre o instante de tempo em
que foi realizada a última gravação no banco de dados e o instante de tempo atual
for maior ou igual ao tempo máximo entre amostras. Vale ressaltar que esse cuidado
Figura 31: Paralelogramo formado pelo desvio sobre a reta
Fonte: Próprio autor
com o tempo entre amostras é importante para manter a precisão de variação entre
os valores das amostras ao longo do tempo. O trecho de código a seguir apresenta o
cálculo do valor esperado e a verificação da pertinência do valor ao paralelogramo.
public static boolean TesteParalelogramo (Valor Gravado, Valor Atual, Valor Recente, double Desv, int Tempo)
{ ... if (ValorGravado <= ValorProximo){ valoresperado = (((ValorRecente-ValorGravado)*(TempoAtual - TempoGravado)) / (TempoRecente - TempoGravado))+ValorGravado;
System.out.println("valor esperado < proximo :"+valoresperado); } else{ valoresperado = (((ValorGravado-ValorRecente)*(TempoRecente - TempoAtual)) / (TempoRecente - TempoGravado))+ValorRecente;
System.out.println("valor esperado > proximo :"+valoresperado); } ... if (TempoProximo - TempoGravado <300) { if ((ValorAtual>valoresperado+desvio)||(ValorAtual< valoresperado-desvio)) { return false; }else return true; }
else return false; }