Guilherme Anderson-PJI2-2020-1

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

Responsaveis

  • Anderson Gaspar, e-mail: andersongasparm@gmail.com
  • Guilherme Lopes Roque, email: guilherme.lroque@gmail.com

Levantamento de Requisitos

Funcionais:

  • RF.01 O sistema deve possuir uma estação Raspberry que servirá como gerenciador de sensores.
  • RF.02 O sistema deve permitir a instalação e remoção física de sensores da estação;
  • RF.03 O sistema deve possuir um servidor WEB (WSGI) para servir de interface com o administrador com o sistema;
  • RF.04 O sistema deve possuir um servidor de fila de mensagens (Broker) para as notificações, leitura e configuração dos limiares dos sensores através de redes externas.
  • RF.05 O sistema deve permitir a configuração valores limites de leitura dos sensores para gatilho das notificações da estação.
  • RF.06 O sistema suportar inicialmente os seguintes sensores:
  1. DHT11

Não funcionais:

  • RNF.01 - O usuário deve possuir um um sistema Linux Debian com interpretador python3 e estar conectado à Internet para interagir com o sistema.
  • RNF.02 - O usuário deve possuir um um sistema Linux Debian com interpretador python3 e instalador pip3 para instalar o sistema.
  • RNF.03 - O software desenvolvido para a estação Raspberry deve ser modular, prevendo futuras melhorias incrementais, como a compatibilidade com outros sensores;

Definições dos sujeitos

  • Sistema Local: Implementado pela estação meteorológica num dispositvo Raspberry. Este atende as requisições dos usuário primário Administrador (atua como sistema na linguagem UML).
  • Sistema Externo: Implementado pela estação meteorológica num dispositvo Raspberry e pelo servidor de fila de mensagens (Broker) num sistema linux. Este atende as requisições dos usuários primário Usuário (atua como sistema na linguagem UML) e exclusivamente no caso de uso Notificação atua como ator primário, sendo o iniciador da interação entre os sujeitos.
  • Administrador: Ator primário representado por uma pessoa física no ambiente local do sistema de estação meteorológica, este interage diretamente com a estação meteorológica na Raspberry através do protocolo HTTP.
  • Usuário: Ator primário representado por uma pessoa física em ambiente externo do sistema de estação meteorológica, este interage com a estação meteorológica por intermédio do Broker através do protocolo AMQP.
  • Sensor: Ator secundário que apenas executa rotinas solicitadas inicialmente pelos atores primários através do Sistema.

Casos de uso

Sistema Local (Estação meteorológica)

Diagrama de caso local

Registrar sensor

Ator primário: Administrador.

Ator secundário: Sensor.


Fluxo principal:

  • O Administrador faz a instalação física do sensor na placa da Raspberry Pi.
  • O Administrador envia uma requisição HTTP contendo os dados do sensor a ser registrado diretamente para a estação meteorológica;
  • O sistema configura e ativa o sensor e responde ao Administrador uma mensagem HTTP de sucesso;

Remover sensor

Ator primário: Administrador

Ator secundário: Sensor.


Fluxo principal:

  • O Administrador envia uma requisição HTTP contendo o identificador do sensor a ser removido diretamente para a estação meteorológica.
  • A estação meteorológica remove o sensor de seus registros e rotinas e responde o Administrador uma mensagem HTTP de sucesso.
  • O Administrador faz desconexão física do sensor na placa da Raspberry Pi


Alterar registro

Ator primário: Administrador

Atores secundários: Sensor

Fluxo principal:

  • O Administrador envia uma requisição HTTP contendo os dados do sensor a ser atualizado diretamente para a estação meteorológica;
  • A estação meteorológica altera os registros do sensor e responde o administrador uma mensagem HTTP de sucesso;


Requisitar dados

Ator primário: Administrador

Atore secundários: Sensor.

Fluxo principal:

  • O administrador envia uma requisição HTTP contendo os dados do sensor a ser lido para a estação meteorológica;
  • A estação meteorológica lê o sensor e responde o usuário uma mensagem HTTP de sucesso com os dados lidos;


Sistema Externo (Estação meteorológica + Broker)

Diagrama de caso externo

Alterar registro

Ator primário: Usuário

Atores secundários: Sensor

Fluxo principal:

  • O usuário envia uma requisição via AMQP contendo os dados do sensor a ser atualizado para o Broker;
  • O Broker executa suas rotinas internas de enfileiramento e roteamento e repassa a requisição para a estação meteorológica.
  • A estação meteorológica altera os registros do sensor e responde o usuário uma com mensagem de sucesso através do Broker;


Requisitar dados

Ator primário: Usuário

Atores secundários: Sensor.

Fluxo principal:

  • O usuário envia uma requisição via AMQP contendo os dados do sensor a ser lido para o Broker;
  • O Broker executa suas rotinas internas de enfileiramento e roteamento e repassa a requisição para a estação meteorológica.
  • A estação meteorológica lê o sensor e responde o usuário com os dados através do Broker;

Notificação

Ator primário: Estação Meteorológica

Atores secundários:Sensor e Usuário.

Fluxo principal:

  • O sistema identifica um valor fora dos limites configurados para o sensor através de sua rotina interna de leitura.
  • O sistema envia para todos os usuários a notificação através do Broker.

Diagrama de Implementação

Diagrama de Implementação

Diagrama de classes

Diagrama Interfaces

Diagrama Interface

Diagrama Driver

Diagrama Driver

Diagrama Usuário

Diagrama Usuario


Modelagem de interações

Notificação

Notificação

Sequência:

  • O usuário se inscreve no Broker para receber notificações através do comando 'amqp-listen'.
  • A instancia da classe AMQPListen invocada pelo comando 'amqp-listen' realiza alguns procedimentos com o Broker, estes representados pela macro 'subscribe', e fica à espera de notificações.
  • O notificador, implementado pela classe 'Publisher' realiza uma leitura do sensor que está fora dos limites máximo e mínimo configurados e então publica a notificação no Broker, através do método 'basic_publish()'.
  • O Broker disponibiliza (macro 'queue') a publicação da estação meteorológica para todos usuários que se inscreveram.
  • A classe AMQPListen consome (macro 'consume') a publicação disponibilizada pelo Broker e notifica o Usuário através da impressão da mensagem no terminal de execução do comando.

Leitura externa

Diagrama de Leitura externa


Sequência:

  • O usuário faz uma requisição de leitura de sensor ao Broker através do comando 'amqp-request -r'.
  • A instancia da classe AMQPRequest invocada através do comando 'amqp-request' publica no Broker a requisição do Usuário através do método 'basic_publish()'.
  • O Broker disponibiliza (macro 'queue') a publicação do Usuário para a instância da classe Consumer da estação meteorológica.
  • A estação meteorológica consome (macro 'consume') a publicação disponibilizada pelo Broker e lê o sensor através do método 'read()'.
  • A estação meteorológica retorna o valor lido para o Broker.
  • O Broker retorna o valor recebido para o Usuário.

Atualização Externa

Configuração Externa

Sequência:

  • O usuário faz uma requisição de configuração do sensor ao Broker através do comando 'amqp-request -c'.
  • A instancia AMQPRequest invocada através do comando 'amqp-request' publica no Broker a requisição do Usuário através do método 'basic_publish()'.
  • O Broker disponibiliza (macro 'queue') a publicação do Usuário para a estação meteorológica.
  • A instância da classe 'Consumer' da estação meteorológica consome (macro 'consume') a publicação disponibilizada pelo Broker e atualiza os registros do sensor.
  • A estação meteorológica retorna uma mensagem de sucesso ao Broker.
  • O Broker retorna a mensagem recebida para o Usuário.

Atualização Local

Configuração Local
  • Através de qualquer aplicação o Administrador envia uma requisição HTTP PUT diretamente a estação meteorológica.
  • A estação meteorológica atualiza os registros do sensor e retorna uma resposta HTTP de sucesso.

Configuração|Leitura Local

Leitura Local

Sequencia configuração:

  • Através de qualquer aplicação o Administrador envia uma requisição HTTP POST diretamente a estação meteorológica.
  • A estação meteorológica registra os dados do sensor, faz a ativação do sensor e retorna uma resposta HTTP de sucesso.

Sequencia leitura:

  • Através de qualquer aplicação o Administrador envia uma requisição HTTP GET diretamente a estação meteorológica.
  • A estação meteorológica lê os dados do sensor e retorna uma resposta HTTP de sucesso com os dados lidos.

Interação com o sistema

Comandos AMQP

Sintaxe:

amqp-request.py -r <sensorID>

amqp-request.py -c <sensorID> -M <max> -m <min> -t <type>

amqp-listen.py

API REST

Exemplos com a aplicação 'curl' disponível para sistemas Linux:

curl --header "Content-Type: application/json" --request POST --data '{"id":"sensor1","max":10,"min":5,"model":"DHT11","data_type":"temperature","type_specific":{"pin":4}}' localhost:5000/sensor

curl --header "Content-Type: application/json" --request PUT --data '{"id":"sensor1","max":8,"min":5,"data_type":"temperature"}' localhost:5000/sensor

curl --header "Content-Type: application/json" --request GET --data '{"id":"sensor1"}' localhost:5000/sensor

curl --header "Content-Type: application/json" --request DELETE --data '{"id":"sensor2"}' localhost:5000/sensor

Instalação do Broker

sudo apt install erlang

sudo apt install rabbitmq-server

sudo rabbitmq-server enable rabbitmq_management

sudo systemctl start rabbitmq-server.service

sudo rabbitmqctl add_user admin admin

sudo rabbitmqctl set_user_tags admin administrator

sudo rabbitmqctl set_permissions -p / admin "." "." "."

Gerenciamento do Broker

O gerenciamento do Broker é feito através do comando 'systemctl' de sistemas linux. Exemplos:

sudo systemctl start rabbitmq-server.service #inicia o serviço

sudo systemctl stop rabbitmq-server.service #interrompe o serviço

sudo systemctl restart rabbitmq-server.service #reinicia

sudo systemctl status rabbitmq-server.service #exibe o estado corrente

Nota: Toda configuração AMQP é feita a partir dos dispositivos finais.

Instalação da Estação Meteorológica

Instalação no sistema Linux Debian

git clone https://github.com/GuilhermeRoque/PJ2.git

cd PJ2/station/

sudo chmod +x installer.sh

sudo ./installer.sh

Instalação com Venv

git clone https://github.com/GuilhermeRoque/PJ2.git

cd PJ2/

python3 -m venv venv

source venv/bin/activate

pip3 install -r requirements.txt

Execução da Estação Meteorológica

Instalação no sistema Debian

Os serviços já estão ativos e sendo gerenciados pelo systemd, o daemon gerencidar do sistema Linux Debian.

Instalação com Venv

cd PJ2/station/interface/

python3 mainWeb.py &

python3 mainPublisherAMQP.py &

python3 mainConsumerAMQP.py &

cd ../driver/

python3 mainDriver.py &

Testes do sistema

Retorno dos comandos AMQP

amqp-request.py -i <IP> -r <sensorID>

Leitura Local

Retorno do "journalctl -u consumerAMQP.service -f"

Leitura Local


amqp-listen.py

Leitura Local

Retorno dos comandos API REST

curl --header "Content-Type: application/json" --request POST --data '{"id":"sensor1","max":10,"min":5,"model":"DHT11","data_type":"temperature","type_specific":{"pin":4}}' localhost:5000/sensor

Leitura Local

Retorno do "journalctl -u webApp.service -f"

Leitura Local


curl --header "Content-Type: application/json" --request GET --data '{"id":"sensor1"}' localhost:5000/sensor

Leitura Local

Retorno do "journalctl -u webApp.service -f"

Leitura Local


curl --header "Content-Type: application/json" --request PUT --data '{"id":"sensor1","max":24,"min":20,"data_type":"temperature"}' localhost:5000/sensor


Leitura Local

Retorno do "journalctl -u webApp.service -f"

Leitura Local

Retorno do "journalctl -u publisherAMQP.service -f"

Leitura Local


curl --header "Content-Type: application/json" --request DELETE --data '{"id":"sensor1"}' localhost:5000/sensor


Leitura Local

Retorno do "journalctl -u webApp.service -f"

Leitura Local

Considerações finais

Conceitos e ferramentas utilizadas

Para desenvolver o sistema final, integrando todos os serviços, foi utilizado no desenvolvimento os seguintes conceitos:

  • Programação multiprocesso: Como é oferecido mais de uma funcionalidade no sistema é necessário definir uma forma de como tudo vai operar em conjunto. Dentre as opções de multiprocessos, multithreading e rotinas assíncronas, foi escolhido o multiprocesso devido a sua maior facilidade de manutenção, operação, e por existir uma evidente distinção entre os serviços oferecidos (leitura de sensor, comunicação WEB e comunicação AMQP.
  • Orientação a objeto: Para maior qualidade de código (abstração, manutenção e estruturação) foi utilizado o paradigma de orientação a objeto (POO).
  • Serviços WEB: Para prover um serviço localmente por meio de interfaces e protocolos padronizados.
  • Comunicação persistente por mensagens: Para prover suporte a comunicação assíncrona e persistente que é necessária num sistema distribuído na internet.


Flask é um micro-framework destinado principalmente a pequenas aplicações com requisitos mais simples, como por exemplo, a criação de um site básico. Possui um núcleo simples e expansível que permite que um projeto possua apenas os recursos necessários para sua execução.

SQLAlquemy é um ORM completo, criado com Python para desenvolvedores de aplicativos, que fornece flexibilidade total do SQL, obtendo um conjunto completo de padrões de persistência de nível corporativo bem conhecidos, que são projetados para acesso a banco de dados eficientes e de alto desempenho.

RabbitMQ é um servidor de mensagens de código aberto desenvolvido em Erlang, implementado para suportar mensagens em um protocolo denominado Advanced Message Queuing Protocol (AMQP). Ele possibilita lidar com o tráfego de mensagens de forma rápida e confiável, além de ser compatível com diversas linguagens de programação, possuir interface de administração nativa e ser multiplataforma. Dentre as aplicabilidades do RabbitMQ estão possibilitar a garantia de assincronicidade entre aplicações, diminuir o acoplamento entre aplicações, distribuir alertas, controlar fila de trabalhos em background.

pika: Pika é uma implementação Python puro do protocolo AMQP 0-9-1 que tenta permanecer bastante independente da biblioteca de suporte de rede subjacente.

Adicionar compatibilidade com sensores

Criar a classe específica do sensor

Esta classe deve conter a lógica de interação com o sensor, devendo implementar os métodos 'read' e 'activate' declarados pela classe abstrata 'Sensor'. Ex: station/driver/dht11.py

Codificar como o driver deve construir o sensor

Esta classe é o 'SensorDriver' em /station/driver/driver.py e deve apenas ser incrementada. Note que esta classe recebe um json via socket com as informações do sensor a ser lido ou ativado e então instancia um objeto da classe específica do tipo do sensor para por fim ler ou ativar o sensor.