Você está na página 1de 159

UNIP - UNIVERSIDADE PAULISTA

LUCAS MATIAS DO ESPIRITO SANTO – D64BCD3

HENRIQUE LINO PACHECO – D844008

ROBERTO DA SILVA SANTANA – D785AF3

JOÃO VICTOR DI PARDI CIRILO – N275243

ESTUDO E PONDERAÇÕES ACERCA DO DESENVOLVIMENTO SOBRE


SOFTWARE EMBARCADO DE COLEIRAS INTELIGENTES PARA ANIMAIS DE
ESTIMAÇÃO

SÃO PAULO
2021
2

LUCAS MATIAS DO ESPIRITO SANTO – D64BCD3

HENRIQUE LINO PACHECO – D844008

ROBERTO DA SILVA SANTANA – D785AF3

JOÃO VICTOR DI PARDI CIRILO – N275243

ESTUDO E PONDERAÇÕES ACERCA DO DESENVOLVIMENTO SOBRE


SOFTWARE EMBARCADO DE COLEIRAS INTELIGENTES PARA ANIMAIS DE
ESTIMAÇÃO

Trabalho de conclusão de curso para obtenção


do título de graduação em Ciência da
Computação apresentado à Universidade
Paulista – UNIP.

Orientador(a): Mestre: Álvaro André Colombero


Prado

SÃO PAULO
2021
3

LUCAS MATIAS DO ESPIRITO SANTO – D64BCD3

HENRIQUE LINO PACHECO – D844008

ROBERTO DA SILVA SANTANA – D785AF3

JOÃO VICTOR DI PARDI CIRILO – N275243

ESTUDO E PONDERAÇÕES ACERCA DO DESENVOLVIMENTO SOBRE


SOFTWARE EMBARCADO DE COLEIRAS INTELIGENTES PARA ANIMAIS DE
ESTIMAÇÃO

Trabalho de conclusão de curso para obtenção


do título de graduação em Ciência da
Computação apresentado à Universidade
Paulista – UNIP.

Aprovado em:

BANCA EXAMINADORA

Prof. Titulação Nome do Professor


UNIP - Universidade Paulista de São Paulo

Prof. Titulação Nome do Professor


UNIP - Universidade Paulista de São Paulo

Prof. Titulação Nome do Professor


UNIP - Universidade Paulista de São Paulo
4

AGRADECIMENTOS

Agradecemos a Deus, pela vida que me deu, e por seu infinito amor.
A todos nossos familiares que nos apoiaram nesta empreitada, pela sua
paciência e compreensão nas horas em que estivemos ausentes desenvolvendo este
trabalho.
Ao professores Álvaro Prado e Miryam de Moraes, por seus ensinamentos e
pelo apoio para nos podermos concluir todos os trabalhos, especialmente esta
monografia.
Aos colegas de curso, pela amizade, companheirismo e colaboração recebidos
durante o curso. E aos demais colegas que de alguma forma contribuição em diversos
trabalhos.
5

RESUMO

Embora existam diversos sites e ongs que ajudam na localização de animais,


muitas vezes em cidades grandes fica muito difícil de recuperar o animal de
estimação. As soluções adotadas normalmente, é ficar vários dias para conseguir
localizar o animal e muitas vezes não havendo êxito na busca.
O presente trabalho apresenta o desenvolvimento de um aplicativo de
geolocalização para o acompanhamento de animais de estimação, com o objetivo de
facilitar a busca do animal através de um dispositivo móvel. O projeto foi segmentado
em duas partes, a primeira na construção da coleira para o uso do animal, e a segunda
refere-se à criação de uma aplicação mobile para monitoramento e localização do
animal através dos dados transmitidos pela coleira.

Palavras-chave: geolocalização, aplicativo, localização de animais,


monitoramento.
6

ABSTRACT

Although there are several websites and NGOs that help in locating animals,
often in large cities it is very difficult to retrieve the pet. The solutions usually adopted
are to stay several days to locate the animal and often the search is unsuccessful.

The present work presents the development of a location application for tracking
pets, with the aim of facilitating the search for animals through a mobile device. The
project was divided into two parts, the first in the construction of the collar for the use
of the animal, and the second refers to the creation of a mobile application for
monitoring and locating the animal through the data transmitted by the collar.

Keywords: geolocation, app, animal location, monitoring.


7

LISTA DE ILUSTRAÇÃO

Figura 1 - Diagrama de Classe.................................................................................. 19


Figura 2 - Diagrama Caso de Uso. ............................................................................ 20
Figura 3 Figura representativa de um ator no diagrama de caso de uso .................. 20
Figura 4 - Relacionamento de dependência. ............................................................. 21
Figura 5 - Conexão de generalização. ...................................................................... 21
Figura 6 - Conexão de associação entre atores. ....................................................... 21
Figura 7 - Conexão de associação entre casos de uso. ............................................ 22
Figura 8 - Conexão de associação entre um ator e um caso de uso ........................ 22
Figura 9 - Ponto de inclusão...................................................................................... 22
Figura 10 - Ponto de extensão .................................................................................. 22
Figura 11 - Itens de agrupamento ............................................................................. 23
Figura 12 - Itens anotacionais. .................................................................................. 23
Figura 13 - Gráfico de uso das linguagens de programação ..................................... 24
Figura 14 - Estrutura orientada a objetos. ................................................................. 25
Figura 15 - Exemplificação de um objeto com métodos e atributos. ......................... 26
Figura 16 - Exemplificação de Herança .................................................................... 27
Figura 17 - Exemplo de uso do JPA .......................................................................... 29
Figura 18 - Visão Geral Spring .................................................................................. 31
Figura 19 - Representação de uma Nuvem Pública .................................................. 33
Figura 20 - Representação de uma Nuvem Híbrida .................................................. 34
Figura 21 - Placa Arduino. ......................................................................................... 42
Figura 22 - Representação gráfica do padrão MVC .................................................. 44
Figura 23 Representação gráfica do padrão MVVM usado no VisualWorks ............. 45
Figura 24 Representação gráfica do padrão MVVM da Microsoft ............................ 45
Figura 25 - Representação gráfica do padrão MVP .................................................. 46
Figura 26 - Representação gráfica de Injeção de Dependência................................ 47
Figura 27 - Arduino Nano .......................................................................................... 57
Figura 28 - Módulo Gprs Gsm ................................................................................... 58
Figura 29 - Placa Protoboard .................................................................................... 59
Figura 30 - NodemCU .............................................................................................. 60
Figura 31 - Chave Gangorra...................................................................................... 61
8

Figura 32 - L7805C Regulador de Tensão 5V ........................................................... 61


Figura 33 - Suporte para 2 Baterias .......................................................................... 62
Figura 34 - Bateria Recarregável 18650 4.2V Li-ion Lítio ......................................... 62
Figura 35 - Protótipo virtual ....................................................................................... 64
Figura 36 - Protótipo físico. ....................................................................................... 65
Figura 37 - Diagrama de casos de uso ..................................................................... 66
Figura 38 - Diagrama de classe se apresenta subdividido em três grupos ............... 71
Figura 39 - Teste da tela de login .............................................................................. 74
Figura 40 - Teste da tela de cadastro ........................................................................ 75
Figura 41 - Teste da tela principal ............................................................................. 76
Figura 42 - Teste de voltagem................................................................................... 78
Figura 43 - Protótipo versão ...................................................................................... 78
9

LISTA DE TABELAS

Tabela 1 - Quadro 1: Documentação do caso de uso "Criar cadastro" ................... 67


Tabela 2 - Quadro 2: Documentação do caso de uso "Login" ................................. 67
Tabela 3 - Quadro 3: Documentação do caso de uso "Adicionar dispositivo" ......... 68
Tabela 4 - Quadro 4: Documentação do caso de uso "Remover dispositivo" ......... 68
Tabela 5 - Quadro 5: Documentação do caso de uso "Deletar cadastro" ............... 69
Tabela 6 - Quadro 6: Documentação do caso de uso "Notificar alteração" ............. 69
Tabela 7 - Quadro 7: Documentação do caso de uso "Receber Dados" ................. 70
Tabela 8 Quadro 8: Documentação do caso de uso "Modificar base de dados" ..... 70
Tabela 9 - Quadro 9: Documentação do caso de uso "Logout"............................... 71
Tabela 10 - Tabela de Testes.................................................................................. 77
10

SUMÁRIO
1 INTRODUÇÃO .................................................................................................... 13
1.1 Contextualização ............................................................................................. 13
1.1.1 Problema ...................................................................................................... 13
1.1.2 Hipótese........................................................................................................ 13
1.2 Motivação ........................................................................................................ 13
1.3 Justificativa ...................................................................................................... 14
1.4 Objetivos .......................................................................................................... 16
1.4.1 Objetivos Gerais ........................................................................................... 16
1.4.2 Objetivos Específicos.................................................................................... 16
1.5 Procedimentos Metodológicos ......................................................................... 16
2 REFERENCIAL TEÓRICO ................................................................................. 18
2.1 UML (Unified Modeling Language) .................................................................. 18
2.1.1 Itens estruturais ............................................................................................ 19
2.1.2 Itens comportamentais.................................................................................. 19
2.2 Java ................................................................................................................. 23
2.2.1 Orientação a objetos ..................................................................................... 25
2.2.1.1 Objeto ........................................................................................................ 26
2.2.1.2 Classe ........................................................................................................ 27
2.2.1.3 Herança ..................................................................................................... 27
2.3 Jpa ................................................................................................................... 28
2.3.1 Orm ............................................................................................................... 28
2.3.2 Anotações da JPA. ....................................................................................... 28
2.4 Spring .............................................................................................................. 30
2.5 Computação em Nuvem .................................................................................. 31
2.5.1 Nuvem pública .............................................................................................. 32
2.5.2 Nuvem privada .............................................................................................. 33
2.4.3 Nuvem híbrida .............................................................................................. 33
2.5 Scrum .............................................................................................................. 34
2.6 Kanban ............................................................................................................ 36
11

2.7 Mvp .................................................................................................................. 37


2.8 Okr ................................................................................................................... 39
2.9 Arduino ............................................................................................................ 41
2.10 Padrões de projeto ........................................................................................ 43
2.10.1 Padrão Modelo-Visão-Controlador.............................................................. 44
2.10.1.1 Padrão Modelo-Visão-Visãomodelo......................................................... 44
2.10.1.2 Padrão Modelo-Visão-Apresentador ........................................................ 46
2.10.2 Inversão De Controle .................................................................................. 46
2.10.2.1 Injeção De Dependência.......................................................................... 47
2.11 História IOT.................................................................................................... 48
2.12 Segurança IOT .............................................................................................. 50
3 COMPOSIÇÃO DO PROJETO ........................................................................... 51
3.1 Ferramentas .................................................................................................... 51
3.1.1 Ec2 (aws) ...................................................................................................... 51
3.1.2 IDE (Eclipse) ................................................................................................. 52
3.1.3 Spring ........................................................................................................... 53
3.1.4 Maven (gerenciador de dependência) .......................................................... 53
3.1.5 Bootstrap (framework para CSS) .................................................................. 54
3.1.6 Postman........................................................................................................ 54
3.1.7 Git ................................................................................................................. 55
3.1.8 Github ........................................................................................................... 55
3.2 Materiais .......................................................................................................... 57
3.2.1 Arduino ......................................................................................................... 57
3.2.2 Módulo Gprs Gsm ......................................................................................... 58
3.2.3 Placa Protoboard .......................................................................................... 59
3.2.4 Módulo NodeMCU ESP8266 ........................................................................ 60
3.2.5 Chave Gangorra com 2 Terminais ................................................................ 61
3.2.6 L7805C Regulador de Tensão 5V ................................................................ 61
3.2.7 Suporte para 2 Baterias ................................................................................ 62
3.2.8 Bateria Recarregável 18650 4.2V Li-ion Lítio ............................................... 62
3.3 Construção do hardware.................................................................................. 63
3.4 Métodos ........................................................................................................... 65
3.4.1 Construção Do Software ............................................................................... 65
12

3.4.2 Diagrama De Casos De Uso ......................................................................... 66


3.4.3 Diagrama De Classe ..................................................................................... 71
4 PLANO DE TESTABILIDADE ............................................................................. 72
4.1 Teste caixa branca .......................................................................................... 72
4.2 Teste da caixa preta ........................................................................................ 73
5 TESTES E RESULTADOS ................................................................................. 76
6 CONCLUSÃO ..................................................................................................... 79
7 REFERÊNCIA BIBLIOGRÁFICA ........................................................................ 81
8 RELATÓRIO COM AS LINHAS DE CÓDIGO ..................................................... 87
8.1 Apêndice A: Código-fonte do servidor ............................................................. 87
8.2 Apêndice B: Código fonte do NodeMCU........................................................ 153
13

1 INTRODUÇÃO

O presente trabalho apresenta uma aplicação que utiliza um sistema


embarcado, destinado a localizar animais desaparecidos com praticidade através de
um aplicativo de celular, que seja acessível e traga segurança aos donos de pets.

1.1 Contextualização
1.1.1 Problema
No ponto de vista do desenvolvimento a viabilidade e a exequibilidade, contribui
para projetar um sistema e equipamentos de rastreio, com objetivo de fornecer uma
localização do cachorro doméstico, e diminuir as chances de desaparecimento, e em
último caso para evitar um problema, ajuda a resgatar o animal de estimação perdido.

1.1.2 Hipótese
No item de exequibilidade, é buscado compreender quais dificuldades práticas
enfrentadas para projetar e desenvolver a solução proposta enquanto na viabilidade
busca-se delimitar a eficiência operativa da solução.
Apesar do grande avanço teórico no que concerne a quais melhores práticas e
métodos para o desenvolvimento de soluções informáticas, há problemas de
aprendizado e adaptabilidade, dado a renovação constante nas preferências
majoritárias, quanto a utilização otimizada de ferramentas emergentes.
Outro ponto a salientar se deve quanto à disponibilidade que a solução irá
ofertar dado que sistemas distribuídos pervasivos não possuem estabilidade dado a
sua característica e necessidade de se adequar a ambientes não otimizados.
Por fim, temos expectativas quanto ao volume de dados, os quais, ao extrapolar
a solução para milhares de pessoas, criaria um volume de dados difícil de administrar,
possuindo potencial de afetar sua viabilidade.

1.2 Motivação
Animais de estimação perdidos não encontrados por seus responsáveis são
um importante fator de contribuição para as populações de animais de estimação
desabrigados, selvagens, abrigos e vadios. Até recentemente, os tutores ficavam por
conta própria com o mínimo de conselhos e nenhuma assistência prática para ajudá-
los a recuperar um animal de estimação perdido. Saber o que fazer nas primeiras 24
14

horas é fundamental e pode significar a diferença entre uma reunião bem-sucedida ou


uma separação permanente. (GRIEGER, 2019)
Existem diversos sites e comunidades na internet que se pode encontrar relatos
de histórias (felizes e tristes) dos donos de seus pets relatando como perderam e
(alguns) encontraram seus animais, como por exemplo, vetstreet.com,
animalhealings.com, petvale.com.br e busca.pet. Com um pouco de conhecimento,
pode-se evitar a perda do seu animal de estimação, mas para garantir, formas de
encontrar seu pet.
Dito isso, quais seriam as melhores maneiras de encontrar um animal de
estimação e como a tecnologia por interferir para favorecer os donos de pets? (TOZZI,
2018)

1.3 Justificativa
As estatísticas de animais perdidos aumentam a cada ano. Com isso, a
organização American Society for the Prevention of Cruelty to Animals (ASPCA)
realizou uma pesquisa com um grupo de donos de animais a respeito de seus animais
de estimação perdidos. No estudo, os pesquisadores coletaram dados sobre quantas
vezes os animais de estimação se perdem de suas casas, a porcentagem de animais
que foram recuperados e, provavelmente, os dados mais importantes que existem: os
métodos que os proprietários usaram para encontrar seus cães ou gatos perdidos.
Havia 1.015 participantes, e todos eles tiveram um cachorro ou gato de estimação nos
últimos cinco anos. De acordo com os participantes, cerca de 14% dos cães e 15%
dos gatos sumiram pelo menos uma vez nos últimos cinco anos. E desse número de
animais perdidos, 93% dos cães e 75% dos gatos foram recuperados. Isso significa
que 7% dos cães e 25% dos gatos nunca foram encontrados. (WEISS, 2012)
De acordo com estatísticas de animais perdidos divulgadas pela ASPCA,
existem 86,4 milhões de gatos e 78,2 milhões de cães nos Estados Unidos. Com base
nas estatísticas acima, o número de animais perdidos que acabam em abrigos todos
os anos é de 5 a 7 milhões.
Existem várias soluções possíveis para esses casos, que resultam no
reencontro dos donos com seus animais de estimação, como animais que são
encontrados na vizinhança, alguns voltam para casa por conta própria e outros foram
devolvidos graças a etiquetas de identificação/coleiras ou microchips.
15

Em um artigo do The Guardian (STORER , 2021), mais de 27.000 pessoas


disseram conhecer alguém cujo cachorro foi roubado no ano passado, embora apenas
cerca de 400 tenham dito que seu próprio cachorro foi roubado. Dependendo de como
um cachorro é roubado, o crime pode ser registrado como furto, isso significa que há
poucos dados sobre a disseminação do roubo de cães ou o que acontece quando um
ladrão de cães é pego. DogLost, uma instituição de caridade do Reino Unido que ajuda
vítimas de roubo de cães, lidou com 465 casos no ano passado, contra 172 em 2019.
As diretrizes oficiais de condenação para roubo classificam os crimes de acordo com
o valor da propriedade roubada, mas os juízes e magistrados podem aumentar a
categoria para itens de valor sentimental.
De acordo com o artigo Spatialities of Dog Theft: A Critical Perspective (ALLEN,
2019), os cães são considerados propriedade pela lei do Reino Unido, enquanto os
proprietários geralmente consideram seus companheiros caninos como uma família.
Relatos de que o número de cães roubados na Inglaterra e no País de Gales
aumentou de 1788 em 2016 para 1909 em 2017. O estudo aponta que houve um
aumento de furto de animais de estimação de 6,03% entre 2015 e 2016, 11,43% entre
2016 e 2017 (e deve-se considerar que esse número pode ser maior já que algumas
companhias não divulgaram dados de crimes reais).
É proposto um sistema de baixo custo para monitoramento de animais de
estimação com base em seus identificadores biométricos primários de animais. São
utilizados métodos de aprendizagem baseados em métricas de similaridade e
distância para combinar e classificar as características extraídas de imagens faciais
para reconhecimento de animais de estimação. A eficácia do sistema de
reconhecimento de animal de estimação proposto é avaliada em aproximadamente
96,8%.(KUMAR, 2018).
No brasil tem animais vivendo nas ruas, sejam eles perdidos ou abandonados.
Com isso, sob o ponto de visto da tecnologia da informação, esse projeto traz a ideia
de um sistema que pode ser gerenciado, para localizar os animais de estimação.
perdidos, Visto que, o projeto trouxe o desafio de muita pesquisa e de
desenvolvimento de um sistema inteligente que engloba a geolocalização, e que
envolve software e hardware. E para o projeto, o sistema auxiliar o usuário a na
localização dos seus animais, e contribui sendo mais um protótipo para a área de
tecnologia.
16

1.4 Objetivos
1.4.1 Objetivos Gerais
Partindo do princípio de que o assunto é desaparecimento de animais de
estimação, a aplicação tem por objetivo facilitar a recuperação ou evitar que os
animais se percam de seus donos com um dispositivo de rastreio. O sistema emprega
a técnica de geolocalização, onde é possível encontrar no mapa a localização do
animal em tempo real. Possibilitando ser possível centralizar todas as informações em
uma única aplicação.

1.4.2 Objetivos Específicos


São os objetivos específicos deste trabalho os listados a seguir:
● Aplicar os diversos conhecimentos teóricos e tecnológicos obtidos no curso de
ciência da computação, em diferentes disciplinas, como modelagem de dados,
programação, banco de dados e engenharia de software, de forma integrada
na resolução de um problema prático.
● Efetuar o levantamento de requisitos e modelagem do aplicativo.
● Desenvolver e testar o aplicativo.

1.5 Procedimentos Metodológicos


O trabalho trata o procedimento metodológico necessário, para caracteriza-se
por uma pesquisa exploratória e descritiva, que possa descrever a pesquisa, atingindo
as características necessárias se mostra adequada aos objetivos propostos.
Segundo Gil (1999), afirma que, “Principal finalidade desenvolver, esclarecer e
modificar conceitos e ideias, tendo em vista a formulação de problemas mais precisos
ou hipóteses pesquisáveis para estudos posteriores.”
A pesquisa exploratória tem como objetivo promover uma primeira
aproximação com o tema, proporcionando ao pesquisador a visibilidade da
importância do problema, o estágio de resolução e as informações
disponíveis. O pesquisador parte de uma hipótese e aprofunda seus estudos
nos limites de uma realidade específica para, em seguida, planejar uma
pesquisa descritiva ou do tipo experimental. Normalmente, a forma de
condução desse tipo de pesquisa é através de levantamento bibliográfico,
entrevistas com profissionais que estudam e/ou atuam na área, visitas a web
sites etc. (MACHADO, 2002)
17

Para TRIVIÑO (1987), “estudo descritivo pretende descrever "com exatidão" os


fatos e fenômenos de determinada realidade.”
As pesquisas descritivas deste tipo têm como objetivo primordial a descrição
das características de determinada população ou fenômeno ou o
estabelecimento de relações entre variáveis. São inúmeros os estudos que
podem ser classificados sob este título e uma de suas características mais
significativas está na utilização de técnicas padronizadas de coleta de dados.
(GIL, 1999)
Para a execução do trabalho, inicialmente foi feita uma pesquisa bibliográfica,
que tem o intuito de apresentar um modelo de uma coleira inteligente, que traz sob a
ótica do projeto, apresentando sistemas dentro do campo da tecnologia, como os
diagramas estruturais abordam tanto os aspectos físicos do sistema quanto os
conceituais. Visto que, também é abordado o diagrama de classes, que é um diagrama
estrutural capaz de mostrar a composição interna das entidades envolvidas, trazendo
uma perspectiva mais estruturada da pesquisa.
Continuamente, foi feita a elaboração do protótipo teórico, que traz em sua
construção duas partes, a física contendo o Hardware e a do Software, que traz o
desenvolvimento apoiado na lógica do protótipo, e com a modelagem de seus
componentes que é baseada nos diagramas da Unified Modelling Language (UML).
Para a validação do modelo, foram feitas diversas análises teóricas, que pode
contribuir no modelo do sistema, trazendo um aspecto de solidificação sobre o projeto
proposto.
Como metodologia base, foram pesquisadas as:
● Pesquisa exploratória e descritiva.
E como métodos fundamentais para a pesquisa:
● Pesquisa bibliográfica, com estudos relacionados Hardware referente a uma
coleira inteligente.
● O desenvolvimento do protótipo, também inclui um software embarcado de
controle baseado na lógica do projeto.
● A parte teórica ficou relacionada apenas nas pesquisas, que engloba o
fundamento da construção do projeto, tendo com a finalidade de validar o
modelo proposto.
18

2 REFERENCIAL TEÓRICO
2.1 UML (Unified Modeling Language)
Segundo (Booch, Rumbaugh, & Jacobson, 2012), a UML (Unified Modeling
Language) é uma linguagem-padrão para a elaboração da estrutura de projetos e
software. Essa linguagem tem como intuito ser empregada para a visualização, a
especificação, a construção e a documentação de artefatos que fazem uso de
sistemas complexos de software.
Essa linguagem é pertinente para modelagem de software, demonstrada
através de diagramas, independentemente da finalidade e complexidade dos
sistemas. Possivelmente, o uso mais comum para criar modelos de sistema de
software, contudo é bastante utilizada também para representar qualquer outro
domínio como telecomunicações, transportes, serviços bancários e financeiros que
não esteja relacionado com software.
Não obstante, a UML não está restrita à modelagem de software. De fato, a
UML é totalmente importante para modelar sistemas que não sejam de software, como
o fluxo de trabalho no sistema legal, a estrutura e o comportamento de sistema de
saúde e o projeto de software. (Booch, Rumbaugh, & Jacobson, 2012)
(Booch, Rumbaugh, & Jacobson, 2012), ainda destaca que a UML é apenas
uma linguagem, portanto, é somente uma parte de um método para desenvolvimento
de software. A UML é independente do processo de software, podendo ser
perfeitamente utilizada em processo orientado a casos de uso, centrado na
arquitetura, iterativo e incremental.
O UML é composto por três tipos de blocos de construção, sendo eles os itens,
relacionamentos e diagramas. Os itens são abstrações como cidadãos de primeira
classe em um modelo; os relacionamentos reúnem esses itens; os diagramas
agrupam coleções de itens. (Booch, Rumbaugh, & Jacobson, 2012)
Dentro do bloco de construção do UML existem quatro tipos de itens, sendo
eles:
1. Itens estruturais
2. Itens comportamentais
3. Itens de agrupamentos
4. Itens anotacionais
19

2.1.1 Itens estruturais


Os diagramas estruturais abordam tanto os aspectos físicos do sistema quanto
os conceituais. Coletivamente, os itens estruturais são chamados de classificadores,
sendo utilizado para visualizar, especificar, construir e documentar os aspectos
estáticos de um sistema. Os aspectos estáticos de um sistema de software abrangem
a existência e a colocação de itens como classe, interfaces, colaborações e
componentes. (Gonçalves & Cortés, 2015)
Diagrama de classes: O diagrama de classes é um diagrama estrutural capaz
de mostrar a composição interna das entidades envolvidas. Um diagrama de classes
exibe um conjunto de classes, interfaces e colaborações, bem como seus
relacionamentos (Booch, Rumbaugh, & Jacobson, 2012). Os diagramas de classes
são mais utilizados em modelagem de sistemas orientados a objeto, capaz de mostrar
a composição interna das entidades envolvidas. Este é possivelmente o diagrama
mais utilizado de UML. (Gonçalves & Cortés, 2015)

Figura 1 - Diagrama de Classe

Fonte: (Booch, Rumbaugh, & Jacobson, 2012, p. 59)

2.1.2 Itens comportamentais


Representam o comportamento do sistema quando está em andamento, ou
seja, a modelagem dinâmica do sistema. São usados para ilustrar as partes que têm
alguma mudança de comportamento, como o fluxo de atividades, a interação entre o
usuário e o sistema e a transição dos estados. (Gonçalves & Cortés, 2015)
Diagrama de casos de uso: Segundo (Gonçalves & Cortés, 2015), este é um
diagrama comportamental utilizado nas fases iniciais do projeto, portanto seu principal
objetivo é explicitar de forma macro (sem detalhes) os requisitos funcionais de um
sistema, partindo do ponto de vista do usuário.
20

Tem uma magnitude de ir além do escopo do sistema e apresentar as


funcionalidades disponibilizadas ao usuário. Dessa forma, o diagrama enfatiza em
assimilar o problema a ser resolvido, tirando o foco do detalhamento da
implementação neste momento. (Gonçalves & Cortés, 2015)
Os elementos disponibilizados pelo diagrama de casos de uso são:
Caso de uso: Demonstra uma funcionalidade que o sistema deve conter. É
representado através de uma elipse que contém o nome do caso de uso.

Figura 2 - Diagrama Caso de Uso.

Fonte: (Gonçalves & Cortés, 2015, p. 47)

Atores: São os responsáveis, direta ou indiretamente, pela interação com o


sistema, podendo ser um usuário ou qualquer entidade externa do sistema.
A notação da UML para representar um ator é uma figura de uma “pessoa” em
forma de palito com o nome do ator abaixo da figura.

Figura 3 Figura representativa de um ator no diagrama de caso de uso

Fonte: (Gonçalves & Cortés, 2015, p. 48)

Relacionamentos: Na UML, um relacionamento é uma conexão entre


elementos de modelo. Um relacionamento UML é um tipo de elementos de modelo
que inclui semântica em um modelo, definindo a estrutura e o comportamento entre
os elementos de modelo.
21

Os relacionamentos UML são agrupados nas seguintes categorias:


Dependência: Representa que uma alteração em um elemento de modelo
pode concernir outro elemento de modelo.

Figura 4 - Relacionamento de dependência.

Fonte: (Gonçalves & Cortés, 2015, p. 48)

Generalização/Especialização: Representam um elemento de modelo é uma


especialização de outro elemento de modelo. Exemplo a seguir demonstrar duas
funções, onde ambas utilizam um mesmo modelo de realizar uma transação:

Figura 5 - Conexão de generalização.

Fonte: (Gonçalves & Cortés, 2015, p. 48)

Associação: Representa as instâncias de um elemento de modelo que estão


conectadas a instâncias de outro elemento de modelo, que pode ser utilizada para
conectar dois atores, dois casos de usos ou um ator e um caso de uso. A seguir
ilustrações do uso da associação entre as entidades do diagrama de caso de uso.

Figura 6 - Conexão de associação entre atores.

Fonte: (Gonçalves & Cortés, 2015, p. 49)


22

Figura 7 - Conexão de associação entre casos de uso.

Fonte: (Gonçalves & Cortés, 2015, p. 49)

Figura 8 - Conexão de associação entre um ator e um caso de uso

Fonte: (Gonçalves & Cortés, 2015, p. 49)

Ponto de Inclusão: É utilizado quando um caso de uso base incorpora um ou


mais casos de uso e o utiliza de maneira obrigatória.

Figura 9 - Ponto de inclusão

Fonte: (Gonçalves & Cortés, 2015, p. 49)

Ponto de Extensão: É utilizado quando um caso de uso base incorpora um ou


mais casos de uso e o utiliza de maneira opcional.

Figura 10 - Ponto de extensão

Fonte: (Gonçalves & Cortés, 2015, p. 50)


23

Itens de agrupamento: São partes organizacionais dos modelos de UML. Ao


todo, existe apenas um tipo principal de itens de agrupamento, chamado pacotes.
Os pacotes são um recurso no qual é utilizado para organização do projeto.
Dentro de um pacote pode haver outros vários itens como, os itens comportamentais,
itens estruturais, e até outros itens de grupos podem ser colocados em pacotes.
(Gonçalves & Cortés, 2015)

Figura 11 - Itens de agrupamento

Fonte: (Booch, Rumbaugh, & Jacobson, 2012, p. 60)

Itens anotacionais: São as partes explicativas dos modelos de UML.


São comentários, incluídos para descrever, esclarecer e fazer alguma
observação sobre qualquer elemento do modelo (Booch, Rumbaugh, & Jacobson,
2012). Uma nota tem como objetivo permitir adicionar informações a um modelo,
podendo ser colocada em qualquer lugar em um diagrama, e pode conter qualquer
tipo de informação.

Figura 12 - Itens anotacionais.

Fonte: (Booch, Rumbaugh, & Jacobson, 2012, p. 60)

2.2 Java
O Java é uma linguagem de programação de alto nível que utiliza o paradigma
de orientação a objetos, desenvolvida para sanar as necessidades do
24

desenvolvimento de aplicações em ambiente distribuído e heterogêneo pela empresa


Sun Microsystems e que atualmente pertence à empresa Oracle. É capaz de criar
aplicativos para desktop, aplicações comerciais, software robustos, completos e
independentes, aplicativos para a Web. (Claro & Sobral, 2008)
A linguagem Java tem um grande benefício que é oferecer a portabilidade.
Todo código fonte é compilado, e no final da aplicação sempre é gerado um arquivo
bytecode que pode ser executado em uma máquina virtual. Sendo assim o
programador não tem a necessidade de sempre escrever códigos diferentes em cada
sistema operacional, a aplicação pode ser escrita uma única vez e ser executada em
qualquer sistema operacional que tenha o Java Vitual Machine instalado.
No momento atual o Java é uma das linguagens mais utilizadas no mundo.
Sendo mais utilizada para desenvolvimento de aplicativos mobile, aplicações desktop
e aplicações web. De acordo com a empresa de qualidade de software TIOBE (TIOBE,
2021), Java está sendo umas das linguagens mais requisitadas nos últimos anos,
conforme mostra o gráfico abaixo:

Figura 13 - Gráfico de uso das linguagens de programação

Fonte: (TIOBE, 2021)

A ilustração do gráfico na Figura 13, é um comparativo das linguagens mais


utilizadas e renomadas durante os últimos anos. Pode-se perceber que a linguagem
Java sempre manteve uma consistência entre as linguagens mais utilizadas no
mercado de trabalho. Durante todos esses anos o Java, conforme o gráfico, apresenta
25

uma grande relevância em comparativo com as outras linguagens por ser útil e
eficiente, podendo proporcionar funções necessárias para o desenvolvimento de
diversos tipos de aplicações.

2.2.1 Orientação a objetos


Orientação a objetos é um paradigma utilizado pelos engenheiros de software
no desenvolvimento de sistemas. Um sistema orientado a objeto é composto por
classes e objetos que interagem entre si, que tem como objetivo principal modelar o
mundo real, e garantir que as taxas de manutenibilidade (manutenção) serão maiores
diante deste contexto. A utilização de uma linguagem orientada a objetos pode-se ter
uma maior qualidade e agilidade no desenvolvimento, pois é possível fazer a
reutilização de códigos que foram desenvolvidos anteriormente. (Claro & Sobral,
2008)
Conforme ilustrado na FIGURA 14, exemplifica um modelo simples de uma
estrutura orientada a objetos, onde podemos ter uma classe PESSOA que possui
atributos (características) tais como: cor_de_olho, cor_de_cabelo, idade. Essa mesma
classe possui métodos (ações, comportamentos) tais como: faz_aniversario,
pintar_cor_de_olho.

Figura 14 - Estrutura orientada a objetos.

Fonte: (Claro & Sobral, 2008, p. 10)

Existem diversos artefatos que separam a programação orientada a objetos da


programação estruturada. Esta seção focará na explicação e exemplificação de:
objetos, classes e herança.
26

2.2.1.1 Objeto
Objeto é uma abstração encapsulada que tem um estado interno dado por uma
lista de atributos cujos valores são únicos para o objeto. O objeto também conhece
uma lista de mensagens que ele pode responder e sabe como responder cada uma.
Um objeto ou instância é uma materialização da classe, sendo assim pode ser
utilizado para representar dados e executar operações. (Claro & Sobral, 2008)
É possível perceber através da figura 15, uma caneta é um objeto da classe
“ClasseCaneta”, que possui atributos e métodos específicos vinculados a ele. No caso
abaixo, os atributos são: modelo, cor, ponta, carga e tampada. Já os métodos
expostos para a chamada no objeto são: escrever, rabiscar, pintar, tampar e
destampar.

Figura 15 - Exemplificação de um objeto com métodos e atributos.

Fonte: Autoria Própria (2021)

As características de um objeto são chamadas de atributos. Esses atributos


estão associados à classe do objeto que determinam suas características. Essas
características devem ser alteradas apenas através de funções específicas chamadas
métodos, por exemplo: caso queira escrever, os métodos destampar e escrever serão
ativados para que possa efetuar a ação.
27

2.2.1.2 Classe
Segundo (Sintes, 2002), uma classe define todas as características comuns a
um tipo de objeto. Especificamente, a classe define todos os atributos e
comportamentos expostos pelo objeto. Como por exemplo, cachorro, aranha e galo
podem ser todos considerados classes herdadas de animais, mas diferenciam-se em
alguns atributos como tamanho, patas e espécies, podendo assim serem classificados
como parte de uma mesma classe superior.

2.2.1.3 Herança
A herança é um mecanismo onde permite que você possa espelhar uma nova
classe na definição de uma classe existente. Segundo (Sintes, 2002), usando a
herança, sua nova classe herda todos os atributos e comportamentos presentes na
classe previamente existente. Quando uma classe herda todos os atributos que
aparecem na interface da classe previamente existente aparecerão automaticamente
na interface da nova classe.
Através da FIGURA 16, um exemplo de herança onde as classes cachorro e
gato são herdadas de uma classe mamíferos, onde terão as mesmas características
como a presença de pelos, glândulas mamárias, diafragma e dentes diferenciados
que são características exclusivas dos mamíferos.

Figura 16 - Exemplificação de Herança

Fonte: Autoria Própria (2021)


28

2.3 Jpa

A Java Persistence API (JPA) é uma especificação Java para acessar,


persistir e gerenciar dados entre objetos/classes Java e um banco de dados
relacional. JPA foi definido como parte da especificação EJB 3.0 como uma
substituição para a especificação EJB 2 CMP Entity Beans. O JPA agora é
considerado a abordagem padrão do setor para Object to Relational Mapping
(ORM) na indústria Java (WIKIBOOKS, 2021).

Faria e Afonso (2020, p. 15) complementam que “[…] o objetivo de uma


especificação não é implementar o produto final, mas definir e padronizar a forma
como os desenvolvedores resolvem determinada coisa”.

2.3.1 Orm
“[...] é uma técnica de programação para conversão do modelo relacional para
o modelo orientado a objetos” (FARIA; AFONSO, 2020, p. 12).
Em banco de dados, as tabelas representam as entidades cujas propriedades
são armazenadas por suas colunas. Uma tabela pode se associar com outras e criar
diversos relacionamentos. Já em linguagens orientada a objetos, como Java,
entidades são classes, e objetos dessas classes representam elementos que existem
no mundo real (FARIA; AFONSO, 2020, p. 13).
Para a conversão ocorrer um mapeamento na classe usando metadados que
relacionam a classe com o modelo relacional do banco é necessário. As operações
CRUD (Create, Read, Update and Delete) são oferecidas pelo ORM através de sua
API apoiadas no relacionamento previamente criado. Os comandos SQL são gerados
durante o uso da API (FARIA; AFONSO, 2020, p. 12-13).

2.3.2 Anotações da JPA.


Anotação é um recurso Java que permite adicionar metadados ao nível de
classe, propriedade, métodos e parâmetros. O mapeamento de JPA faz uso desse
recurso. Na imagem 17, segue exemplo de duas classes entidades que se relacionam
e foram mapeadas com JPA.
29

Figura 17 - Exemplo de uso do JPA

Fonte: (JPA guia definitivo, 2020, p. 106-107 com adaptações).

Abaixo seguem as definições das anotações JPA segundo Faria e Afonso


(2020):
• @Entity: Anotação de nível de classe que informa que esta é uma entidade
JPA, que representa uma tabela do banco de dados.
• @Table: Anotação opcional de nível de classe com propriedade name a qual
informa nome da tabela ao JPA. Sem a anotação JPA iria supor o nome da
tabela como sendo o mesmo da classe acrescido de um ‘s’ ao final do nome.
• @Id: Anotação de nível de propriedade usada para declarar o identificador da
entidade, ou seja, representa o mapeamento da chave primária na tabela do
banco de dados.
• @GeneratedValue: Anotação de nível de propriedade que especifica que um
valor será gerado automaticamente para este atributo. Definimos a estratégia
de geração do identificador através da propriedade strategy com o valor
GenerationType.IDENTITY. A estratégia IDENTITY especifica que o valor será
autoincrementado pela própria coluna do banco de dados. Ou seja, ao inserir
um novo registro, esperamos que o próprio banco de dados tome conta do
incremento para o código do veículo.
• @Column: Anotação opcional para propriedade da entidade com duas de suas
propriedades. Propriedade length informa limite de caracteres aceitos e nullable
informa se a coluna aceita valores nulos.
30

• @ManyToOne: Anotação de propriedade que indica a multiplicidade


relacionamento entre as duas entidades, no caso, muitos produtos para uma
categoria. A propriedade optional informa se no momento da montagem de
queries seria obrigatório ou não a inclusão de joins relacionado a este
relacionamento.
• @OneToMany: Anotação de propriedade que indica a unicidade do
relacionamento entre as duas entidades, no caso, uma categoria para muitos
produtos. A propriedade obrigatória mappedBy deve ser igual ao nome da
propriedade na classe Produto que associa com Categoria.

2.4 Spring
O Spring é um framework Java, criado com o objetivo de facilitar o
desenvolvimento de aplicações, Segundo (WALLS & Breidenbach, 2008).

O Spring é um framework de código aberto criado por Rod Johnson e descrito


em seu livro, Expert One-on-One: J2EE Design and Development. Foi criado
para lidar com a complexidade de desenvolvimento de aplicativos
corporativos. O Spring torna possível usar simples JavaBeans para conseguir
coisas que só eram possíveis com EJBs. Porém, a utilidade do Spring não é
limitada ao desenvolvimento do lado servidor. Qualquer aplicativo Java pode
se beneficiar do Spring em termos de simplicidade, testabilidade e baixo
acoplamento.

Spring fornece muitas funcionalidades de estrutura como gerenciamento de


transações, integração de frameworks de persistências de objetos, e é considerado
um container que gerencia o ciclo de vida e a configuração de objetos do aplicativo.
Segundo (WALLS & Breidenbach, 2008), um dos conceitos chaves do Spring
framework é a injeção de dependência (DI) e a programação orientada a aspectos.
31

Esse framework é segmentado em várias partes, conforme a imagem abaixo:

Figura 18 - Visão Geral Spring

Fonte: (Pacheco, 2007)

A utilização do Spring traz um ganho considerável com relação a qualidade de


software em termos de design patterns. Segundo (Pacheco, 2007), com a utilização
do Spring praticamente anula o uso de patterns como Factory e ServiceLocator.

2.5 Computação em Nuvem


Segundo (Veras, 2012), computação em nuvem é um conjunto de recursos
virtuais facilmente utilizáveis e acessíveis, tais como hardware, software, plataformas
de desenvolvimento e serviços. Uma tecnologia que permite acesso remoto a
programas (software), arquivos (documentos, músicas, jogos, fotos, vídeos) e serviços
por meio da internet, se tornando um grande fator na indústria da tecnologia,
oferecendo diversos benefícios como custos, flexibilidade e segurança conforme
abaixo:
32

Custo: A computação em nuvem descarta o gasto com a compra de hardware


e software, não sendo necessário o ambiente físico para armazenamento de
documentos. Além disso, anula problemas relacionados ao servidor local ou gastos
com manutenção.
Flexibilidade: Os provedores de computação em nuvem oferecem toda uma
infraestrutura para a escalabilidade da aplicação, sem a necessidade de modificação
da infraestrutura de TI. O acesso aos serviços disponibilizados pelos provedores é
pago conforme o consumo. Logo, se houver mudança de produção, basta atualizar o
plano com as novas especificações.
Segurança: A segurança dos dados é um quesito muito preocupante quando
se fala em armazenamento online. Contudo, os serviços em cloud tem um grande
cuidado quando se fala em segurança, oferecendo muito mais segurança do que os
serviços comuns.
Os sistemas de cloud oferecem uma série de proteções, como possibilidade de
o administrador da conta adicionar suas próprias medidas de segurança, tecnologia
de firewall que previne acessos suspeitos e a entrada de vírus, criptografia de ponta
a ponta, e outras diversas formas de proteção.

2.5.1 Nuvem pública


Nuvens públicas representam a computação em nuvem, no modelo
convencional, no qual os recursos são provisionados dinamicamente em uma base de
auto entendimento através da internet, aplicações web ou serviços web, a partir de
um site, provedor de terceiros que compartilham recursos e as contas em granulação
fina, com base de computação utilitária. (Mather, Kumaraswamy, & Latif, 2009)
Nuvem pública é providenciado publicamente no modelo pague-por-uso. De
acordo com (Veras, 2012), são oferecidas por organizações públicas ou por grandes
grupos industriais que possuem grande capacidade de processamento e
armazenamento.
Em uma nuvem pública, o gerenciamento de segurança e as operações diárias
são consignadas ao fornecedor terceirizado, que é responsável pela oferta de serviço
de nuvem pública. Por conseguinte, o cliente do serviço de nuvem pública tem um
baixo grau de controle e supervisão do físico e aspectos lógicos de segurança de uma
nuvem privada. (Mather, Kumaraswamy, & Latif, 2009)
33

Figura 19 - Representação de uma Nuvem Pública

Fonte: (Mather, Kumaraswamy, & Latif, 2009, p. 24)

2.5.2 Nuvem privada


Nuvem privada é uma estrutura oferecida para ser utilizada pela própria
organização, não sendo disponibilizada para uso geral. Segundo (Veras, 2012),
nuvem privada compreende uma infraestrutura de CLOUD COMPUTING operada e
quase sempre gerenciada pela organização cliente, porém em alguns casos pode ser
gerenciada por terceiros.
Cloud Private (Nuvem Privada), está aplicado em um ambiente protegido
(firewall), necessário para situações em que a empresa que necessita de acesso
restrito, aos seus colaboradores e parceiros de negócios.
De acordo com o livro de (Veras, 2012), uma pesquisa realizada pela Forbes
Insights com 235 CIOs e outros executivos de grandes companhias americanas,
apresenta que 52% das organizações estão analisando a migração para nuvem
privada. E ainda é sugerido dois tipos básicos de nuvem privada:
Nuvem Privada, hospedada pela empresa: É um modelo interessante quando
aspectos de compliance e controle precisam ser considerados.
.
2.4.3 Nuvem híbrida
Uma nuvem híbrida é uma infraestrutura que consiste na composição entre
nuvem pública e nuvem privada. Com uma nuvem híbrida, as organizações permitem
34

a execução de serviços que não são necessariamente exigidos pela empresa, sendo
assim, que podem ser repassados para uma empresa terceira, hospedada em uma
nuvem pública e mantendo os principais aplicativos e dados confidenciais
armazenados internamente em uma nuvem privada. (Mather, Kumaraswamy, & Latif,
2009).

Figura 20 - Representação de uma Nuvem Híbrida

Fonte: (Mather, Kumaraswamy, & Latif, 2009, p. 25)

Pode-se concluir, que esse modelo de infraestrutura no qual alguns recursos


são disponibilizados por meio de uma nuvem privada interna e outros recursos por
provedores de serviços de terceiros na nuvem pública.

2.5 Scrum
Scrum é uma forma ágil de gerenciar um projeto, geralmente o
desenvolvimento de software. O desenvolvimento ágil de software com Scrum é
frequentemente percebido como uma metodologia/uma estrutura para gerenciar um
processo. (ABRAHAMSSON, 2002)
Em vez de fornecer descrições completas e detalhadas de como tudo deve ser
feito em um projeto, muito disso é deixado para a equipe de desenvolvimento de
software Scrum. Isso ocorre porque a equipe saberá melhor como resolver o problema
que lhes é apresentado. (ALMEIDA, 2019)
35

É por isso que no desenvolvimento do Scrum, por exemplo, uma reunião de


planejamento da sprint é descrita em termos do resultado desejado (um compromisso
com um conjunto de recursos a serem desenvolvidos na próxima sprint) em vez de
um conjunto de critérios de entrada, definições de tarefas, validação critérios, critérios
de saída e assim por diante, como seriam fornecidos na maioria das metodologias.
(ZANATTA, 2004)
A equipe é auto-organizada, já que não há um líder geral da equipe que decide
qual pessoa fará cada tarefa ou como um problema será resolvido. Essas são
questões que são decididas pela equipe como um todo. Uma equipe é multifuncional,
o que significa que todos são necessários para levar um recurso desde a ideia até a
implementação. (ZANATTA, 2004)
No desenvolvimento ágil, as equipes são apoiadas por duas funções
específicas. O primeiro é um ScrumMaster, que pode ser considerado um coach para
a equipe, ajudando os membros da equipe a usar o processo Scrum para ter um
desempenho de alto nível. No desenvolvimento de software Scrum, representa o
negócio, clientes ou usuários e orienta a equipe para construir o produto certo.
(ZANATTA, 2004)
O modelo Scrum sugere que os projetos progridem por meio de uma série de
sprints. Para manter uma metodologia ágil, as sprints são limitadas no tempo para não
mais de um mês, mais comumente duas semanas. A metodologia defende uma
reunião de planejamento no início da sprint, onde os membros da equipe descobrem
em quantos itens podem se comprometer e, em seguida, criam um backlog da sprint
- uma lista das tarefas a serem executadas durante a sprint. (ABRAHAMSSON, 2002)
Durante uma sprint, a equipe pega um pequeno conjunto de recursos da ideia
à funcionalidade codificada e testada. No final, esses recursos são concluídos, ou
seja, codificados, testados e integrados ao produto ou sistema em evolução. Em cada
dia da sprint, todos os membros da equipe devem participar de uma reunião diária do
Scrum, incluindo o ScrumMaster e o proprietário do produto. Esta reunião tem prazo
limitado para não mais de 15 minutos. Durante esse tempo, os membros da equipe
compartilham o que trabalharam no dia anterior, trabalharão naquele dia e identificam
quaisquer impedimentos ao progresso. O modelo Scrum vê os scrums diários como
uma forma de sincronizar o trabalho dos membros da equipe enquanto eles discutem
o trabalho da sprint. (ALMEIDA, 2019)
36

No final de uma sprint, a equipe conduz uma revisão de sprint durante a qual a
equipe demonstra a nova funcionalidade para o product owner ou qualquer outra parte
interessada que deseja fornecer feedback que possa influenciar a próxima sprint. Este
ciclo de feedback dentro do desenvolvimento do software Scrum pode resultar em
mudanças na funcionalidade recém-entregue, mas também pode resultar na revisão
ou adição de itens ao backlog do produto. (ALMEIDA, 2019)
Outra atividade no gerenciamento de projetos Scrum é a retrospectiva da sprint
ao final de cada sprint. Toda a equipe participa dessa reunião, incluindo o
ScrumMaster e o PO. A reunião é uma oportunidade para refletir sobre a sprint
encerrado e identificar oportunidades de melhoria.
O principal artefato no desenvolvimento do Scrum é, obviamente, o próprio
produto. O modelo Scrum espera que a equipe traga o produto ou sistema a um estado
potencialmente entregável ao final de cada sprint. O 'backlog' do produto é outro
artefato do Scrum. Esta é a lista completa das funcionalidades que ainda precisam ser
adicionadas ao produto. O product owner prioriza o backlog para que a equipe sempre
trabalhe nos recursos mais valiosos primeiros. (ALMEIDA, 2019)

2.6 Kanban
O método Kanban é um meio de projetar, gerenciar e melhorar os sistemas de
fluxo para o trabalho do conhecimento. O método também permite que as
organizações comecem com seu fluxo de trabalho existente e conduzam mudanças
evolutivas. Eles podem fazer isso visualizando seu fluxo de trabalho, limitar o trabalho
em andamento e interromper o início e começar a terminar. (SERENO, 2011)
Kanban é uma metodologia ágil que não é necessariamente iterativa.
Processos como Scrum têm iterações curtas que imitam o ciclo de vida de um projeto
em pequena escala, tendo um início e um fim distintos para cada iteração voltado para
a entrega just-in-time para evitar sobrecarga da equipe. Kanban permite que o
software seja desenvolvido em um grande ciclo de desenvolvimento. (JUNIOR, 2008)
O princípio por trás do Kanban, que permite que ele seja incremental e ágil, é
o rendimento limitado. Sem iterações, um projeto Kanban não tem pontos de início ou
término definidos para itens de trabalho individuais; cada um pode começar e terminar
independentemente um do outro, e os itens de trabalho não têm duração
predeterminada para esse assunto. Em vez disso, cada fase do ciclo de vida é
37

reconhecida como tendo uma capacidade limitada de trabalho a qualquer momento.


Um pequeno item de trabalho é criado a partir da lista de requisitos priorizados e não
iniciados e, em seguida, começa o processo de desenvolvimento, geralmente com a
elaboração de alguns requisitos. Um item de trabalho não tem permissão para passar
para a próxima fase até que alguma capacidade seja disponibilizada adiante. Ao
controlar o número de tarefas ativas a qualquer momento, os desenvolvedores ainda
abordam o projeto geral de forma incremental. (SERENO, 2011)
Kanban pode ser usado em qualquer ambiente de trabalho de conhecimento e
é particularmente aplicável em situações em que o trabalho chega de uma forma
imprevisível e/ou quando você deseja implantar o trabalho assim que estiver pronto,
ao invés de esperar por outros itens de trabalho. (PANNEERSELVAM, 2007)
Quando usado para desenvolvimento de software, Kanban usa os estágios do
ciclo de vida de desenvolvimento de software para representar os diferentes estágios
do processo de manufatura. O objetivo é controlar e gerenciar o fluxo de recursos para
que o número de recursos que entram no processo corresponda ao que está sendo
concluído.
Pode ser usado independentemente do setor. Um editor de conteúdo pode usá-
lo, bem como um negócio de comércio eletrônico. (DALLERY, 2000)

2.7 Mvp
Um produto mínimo viável (MVP) é um conceito que enfatiza o impacto do
aprendizado no desenvolvimento de novos produtos. Essa metodologia é bastante
popular no mundo do desenvolvimento de software. Ele pressupõe a divisão do projeto
em partes menores chamadas iterações. O resultado de cada iteração é um software
funcional que permite coletar o feedback, analisá-lo e seguir em frente. Este termo
significa simplesmente: a coisa com o mínimo de recursos que você pode construir
que irá abordar a oportunidade bem o suficiente para a maioria de seus clientes-alvo
e validar seu mercado e produto. (FARIA, 2017)
Com essa abordagem, você constrói a coisa mais simples possível, reúne
dados sobre como os clientes os usam e, em seguida, refina o produto, se necessário.
Isso permitirá que você trabalhe com bastante eficácia, criando apenas os recursos
que os clientes desejam e usarão, em vez de perder tempo criando coisas com as
quais os clientes não se importam. (FARIA, 2017)
38

O maior benefício de desenvolver um MVP é que ele permite testar vários


modelos e conceitos de negócios. Ao oferecer o conjunto básico de funções em vez
de um produto com muitos recursos, você pode verificar se o conceito do produto está
de acordo com o seu modelo de negócios, proporcionando uma oportunidade de
mudar a direção de um produto com base nas descobertas. Ao contrário dos produtos
com muitos recursos, quando o MVP for iniciado, você terá a capacidade de identificar
quais tipos de grupos sociais são os usuários mais ativos, como eles interagem com
o produto e como você pode monetizá-lo. (FERENTZ, 2021)
Os produtos de qualidade são o resultado de anos de desenvolvimento, com
um preço adequado. Mas, como esses produtos foram criados iterativamente por um
período mais longo, o custo é distribuído ao longo do tempo. A abordagem MVP
também ajuda a economizar, evitando que o produto se torne muito complicado. À
medida que o produto começa a ganhar mais tração e a reunir mais informações sobre
a direção para a qual o produto está se movendo, você pode aumentar ou reduzir seus
investimentos. (FERENTZ, 2021)
Ao desenvolver uma versão de novos produtos, a maioria das pessoas não é
suficientemente rigorosa na definição dos problemas que estão tentando resolver e
articulando porque esses problemas são importantes. Sem esse processo, o produto
pode perder oportunidades e desperdiçar recursos. É por isso que você precisa se
tornar melhor em fazer as perguntas certas para que eles resolvam os problemas
certos. (FERENTZ, 2021)
Assim que você descobrir qual problema está resolvendo, é hora de ver como
outras empresas estão resolvendo esse problema - ou pelo menos tentando resolvê-
lo. Neste ponto, é óbvio que você deve realizar uma análise do concorrente se houver
produtos semelhantes no mercado. Você também deve ter em mente que, mesmo se
você não achar que tem concorrentes diretos, sua fé na exclusividade de seu produto
será o fundamento para levar seu produto ao mercado com segurança. (FERENTZ,
2021)
Definir o fluxo do usuário para seu produto futuro envolve você se concentrar
diretamente em seu objetivo principal. Para definir o fluxo do usuário principal,
devemos primeiro definir as etapas do processo, o que é realmente fácil porque tudo
o que você precisa fazer é explicar as etapas necessárias para atingir o objetivo
principal do seu produto. Neste ponto, você não deve pensar em recursos - mas deve
39

se concentrar em tarefas básicas, como tipos de objetivos que seus usuários finais
têm quando usam seu produto, suas expectativas, etc. Depois de definir o fluxo do
usuário, você pode passar para o wireframing, que é simplesmente uma ilustração de
uma página da web ou de um aplicativo. Um wireframe é um layout que articula que
tipo de elementos de interface encontrarão um lugar em páginas importantes.
(FERENTZ, 2021)
Passando para o estágio de desenvolvimento, você precisa testar seu produto
e trabalhar para melhorar sua qualidade. Após a aprovação dos Wireframes, você
deve começar a trabalhar na arquitetura de configuração, banco de dados e começar
a desenvolver API e todo o back-end. (FARIA, 2017)
Quando um produto que está pronto para o mercado, é necessário fazer testes
beta abertos ou fechados, onde convidamos usuários relevantes para o programa de
teste beta e coletamos feedback sobre funcionalidades e bugs. (FARIA, 2017)
Como o aplicativo está recebendo mais usuários, alguns bugs podem aparecer
e temos a certeza de consertar tudo o mais rápido possível. Normalmente, lançamos
novas compilações a cada dois dias. Depois que o aplicativo estiver estável e tivermos
uma taxa de usuários sem falhas de mais de 99,9%, poderá começar com o marketing
para adquirir mais usuários. (FERENTZ, 2021)

2.8 Okr
Os OKRs podem trabalhar em qualquer nível, do corporativo ao individual. Os
níveis mais altos são avaliados uma vez por ano, enquanto os grupos menores podem
ser avaliados com mais frequência. As notas são baseadas em um resultado (como
lucratividade), em uma escala de 0 a 1, em que 1 é o cumprimento de 100% da meta
para o período. (SANTANA, 2019)
Essas metas se propagam desde a visão da empresa até a forma como as
equipes apoiam essa visão. Isso é chamado de cascata porque esses objetivos são
negociados. Os departamentos podem propor uma medição diferente ou um objetivo
diferente. Isso significa que uma equipe pode ser dona de suas metas e planos.
(SANTANA, 2019)
Estar alinhado e garantir que sua equipe esteja avançando na mesma direção
não é uma tarefa fácil. Os números falam por si - apenas 41% dos funcionários sabem
o que sua organização representa e apenas 38% dos trabalhadores se sentem
40

engajados em seus empregos. E se as pessoas não entendem e não se conectam


com a missão e visão da organização, elas não podem contribuir para a realização
das metas da empresa de forma eficaz. (CASTRO, 2017)
Para evitar esse desalinhamento, muitas empresas começaram a adotar a
metodologia OKR para melhorar o alinhamento e a transparência. Os OKRs só
começaram a ganhar popularidade na década de 1990, quando o Google os adotou.
Na mesma época, as empresas começaram a sentir a necessidade de um novo
método de desenvolvimento, mais iterativo e incremental, e as metodologias ágeis
começaram a ganhar manchetes. (CARDOSO, 2020)
Os OKRs são uma forma poderosa para as empresas criarem clareza, cultura
de transparência e foco no que é mais importante. Isso garante que os funcionários
estejam engajados e animados para entregar seu melhor trabalho em busca de um
propósito comum. Normalmente, os objetivos e os principais resultados são
organizados trimestralmente. Por outro lado, as metodologias ágeis usam iterações
mais curtas de algumas semanas para agregar valor. Pode não ser evidente à primeira
vista, mas algo que os OKRs e as outras metodologias têm em comum é o objetivo
de preencher a lacuna entre estratégia e execução e melhorar a adaptabilidade. Com
isso em mente, existem maneiras de aproveitar as práticas recomendadas de ambas
as metodologias para acelerar o progresso. (CARDOSO, 2020)
A fase de planejamento é quando o escopo deve ser identificado - algumas
empresas começam estabelecendo objetivos no nível da empresa, enquanto outras
podem optar por começar com apenas um departamento e desenvolver nos trimestres
seguintes. No estágio de planejamento, o Dono do Produto OKR, Scrum Master,
Champion e Stakeholders devem ser indicados. A estrutura de logística e tempo
também deve ser definida. (CASTRO, 2017)
A próxima etapa é projetar seus OKRs - descobrir quais são os objetivos
estratégicos e avaliar suas prioridades.
Em seguida, desenvolva isso disseminando os objetivos estratégicos para as
diferentes áreas e identifique os nós de desempenho críticos que devem ser tratados.
Isso o ajudará a criar alinhamento e lhe dará uma visão geral da realização geral da
estratégia. Nesse estágio, os resultados-chave também devem ser identificados - isso
pode ser feito por todos na organização. (CARDOSO, 2020)
41

Como parte do processo de sistematização, certifique-se de determinar com


que frequência os resultados-chave devem ser atualizados - que pode ser semanal,
quinzenal ou mensal, dependendo das necessidades do seu negócio.
Deve considerar a incorporação dos OKRs em suas reuniões e atividades do
dia a dia:
Pode tentar configurar discussões semanais e mensais para fechar sprints,
atualizar o progresso do OKR e refinar as táticas. As reuniões trimestrais podem ser
usadas para atualizar suas prioridades estratégicas e definir novos objetivos e
resultados-chave. Uma vez por ano, reavalie as prioridades, a estratégia geral e
atualize os objetivos estratégicos. Considerar dividir cada sprint em 2 partes - metade
do tempo as equipes devem trabalhar para alcançar um OKR e a outra metade - para
entregar o que as partes interessadas trouxeram em movimento e requerem sua
atenção. Usando sprints, você está sempre se movendo e as coisas acontecem tão
rapidamente que pode ser difícil ter visibilidade em toda a empresa e comunicar a
todos os departamentos o que foi enviado. (SANTANA, 2019)

2.9 Arduino
O Arduino é uma plataforma de hardware open source, projetada sobre o
microcontrolador Atmel AVR, que pode ser utilizado para programar através de uma
linguagem de programação similar a C/C++, permitindo a elaboração de projetos com
um conhecimento mínimo ou mesmo nenhum de eletrônica, com isso, foi criado com
o objetivo de fornecer uma plataforma de fácil prototipação de projetos interativos,
unindo software e hardware, com as características da Computação Física. Visto que,
a Computação Física é uma área da Computação na qual o software se comunica
diretamente com o hardware, podendo controlar componentes eletrônicos, como
sensores e atuadores, permitindo construir sistemas que consigam perceber e
interagir com ambientes reais. (ZANETTI, 2015)
A placa Arduino é muito similar à de um computador de pequeno porte, sendo
composto por um microcontrolador, memória RAM, armazenamento secundário
(memória flash) e clock, entre outras funcionalidades. Na placa do Arduino, temos o
modelo Uno, que é um dos modelos mais vendidos e bastante indicado para os
iniciantes na plataforma. Este modelo apresenta 14 pinos que podem ser utilizados
como entradas ou saídas digitais (pinos 1 a 14), e os pinos 3, 5, 6, 9, 10 e 11 podem
42

ser utilizados para gerar um conjunto de valores inteiros entre 0 e 1.023 pela técnica
de Pulse Width Modulation (PWM), os pinos A0 a A5 correspondem as entradas
analógicas, enquanto os 3, 3 V, 5V e GND (Terra) permitem alimentar os componentes
dos circuitos conectados ao Arduino. Possui um microprocessador ATmega328, com
uma memória RAM de 2 KB, memória Flash de 32 KB e velocidade de clock de 16
MHz. (ZANETTI, 2015)

Figura 21 - Placa Arduino.

Fonte: (ZANETTI, 2015).

No entanto, mesmo tendo similaridades com computadores convencionais,


uma das principais diferenças do Arduino, está na forma de como utilizamos as
entradas e saídas. Por exemplo, em um computador pessoal, conecta teclado e
mouse para entradas, e monitores e impressoras para saídas. No Arduino, as entradas
e saídas já estão diretamente ligadas aos componentes eletrônicos. Nessa situação,
por exemplo, podendo utilizar uma entrada do Arduino que pode estar lendo o valor
de um sensor de temperatura interpretando-o e dando como resposta, um
acendimento de um LED. (ZANETTI, 2015)
Além disso, assim como em qualquer dispositivo de programação, a plataforma
do Arduino necessita que os softwares sejam desenvolvidos, utilizando uma
linguagem de programação, para que sejam compilados, e posteriormente,
transferidos para o Arduino, de uma forma que seja possível a execução dos
comandos utilizados no programa. Para que tenha um intuito de facilitar e tornar o
processo mais fácil e produtivo. (ZANETTI, 2015)
43

Portanto, o Arduino tem essa intenção de criar uma maneira descomplicada de


aprender eletrônica, e por esse motivo a placa Arduino deve ser vista não só́ como
uma plataforma de prototipagem simples para iniciantes, mas também como uma
maneira de você̂ perder o medo de aprender eletrônica. Visto que, a ideia principal
desta placa é possibilitar e facilitar com que pessoas com o mínimo de curiosidade,
possam criar pequenos ou grandes projetos, além de aprender com eles,
possibilitando também descobrir as funções de cada componente eletrônico de
maneira simples, segura e confortável. E principalmente de possibilitar o uso de
recursos para realizar novas criações. (ZANETTI, 2015)

2.10 Padrões de projeto


Alexander (1977, apud ZHANG; BUDGEN, 2012, p. 1215), um teórico de
arquitetura e design, cunhou o termo pattern language como sendo uma descrição de
problemas e suas respectivas soluções de modo que elas possam ser aplicadas
repetidas vezes sem nunca serem executadas da mesma forma.
Gamma et al. (1995, apud HUSSAIN; KEUNG; KHAN, 2017) cataloga 23
padrões de projeto e apontam que tais padrões abrange muitas das estruturas que
resultam da refatoração e que usá-los no início da vida de um projeto evita a
refatoração posterior. Com isso, continua, conclui-se que padrões de projeto, portanto,
fornecem alvos para aquilo que precise de refatoração.
Ao analisar 51 projetos de código aberto e 9 versões subsequentes, Hussain,
Keung e Khan (2017) observaram dois importantes pontos numa análise de nível de
sistema:
● Há correlação positivam significativa entre o uso de padrões de projeto e a
qualidade do software, e;
● O tamanho do projeto influencia na correlação.
Contudo, Zhang e Budgen (2012, p. 1227) apesar de observarem razoável
melhora na comunicação entre desenvolvedores ao usar padrões de projeto, não
identificaram evidências de que novatos tenham algum ganho de entendimento das
soluções implementadas.
44

2.10.1 Padrão Modelo-Visão-Controlador


A programação Modelo-Visão-Controlador (MVC) é um padrão onde objetos
são classificados em três grupos distintos executando operações relacionadas com o
domínio da aplicação (o modelo), a visualização do estado da aplicação (a visão), ou
a interação do utilizador com o modelo e a visão (o controlador) (KRASNER; POPE,
1988, p. 2).
Separando o domínio das preocupações com a interface do usuário torna mais
fácil para o desenvolvedor compreender e modificar cada unidade particular, sem ter
que saber tudo sobre as outras unidades (KRASNER; POPE, 1988).

Figura 22 - Representação gráfica do padrão MVC

Fonte: (KRASNER; POPE, 1988)

“No entanto, não fornece meios explícitos para lidar com estado [de dados] na
visão, (item) que não faz parte do modelo” (SYROMIATNIKOV; WEYNS, 2014, p. 24).
Isso culmina em “uma lógica de estado de visão inadequada” (SYROMIATNIKOV;
WEYNS, 2014, p. 30).

2.10.1.1 Padrão Modelo-Visão-Visãomodelo


Com intuito de se ter um controle explícito e transparente dos estados dos
dados apresentados na visão, surgiu-se o padrão Modelo-Visão-VisãoModelo
45

(MVVM). Embora um mesmo padrão, surgiram implementações diferentes para o


mesmo.
VisualWorks, um ambiente multiplataforma de desenvolvimento para a
linguagem Smalltalk implementou o padrão MVVM (figura 2) adicionando a camada
de modelo da aplicação. Tal camada é responsável por manipular os estados na visão
e acionar métodos conforme mudanças ocorridas no modelo.
Na implementação da Microsoft ao MVVM (figura 3) a camada intermediária
ViewModel embora possa fazer o mesmo da implementação anterior, ela permite que
elementos da visão se vinculem a ela de modo a proporcionar automática
sincronização de dados. (SYROMIATNIKOV; WEYNS, 2014).

Figura 23 Representação gráfica do padrão MVVM usado no VisualWorks

Fonte: (SYROMIATNIKOV; WEYNS, 2014)

Figura 24 Representação gráfica do padrão MVVM da Microsoft

Fonte: (SYROMIATNIKOV; WEYNS, 2014)


46

2.10.1.2 Padrão Modelo-Visão-Apresentador


Introduzido por subsidiária da IBM e popularizado por Dolphin, um ambiente de
desenvolvimento de Smalltalk para Windows, o padrão Modelo-Visão-Apresentador
(MVP, figura 4) implementa sua camada Presenter ao lado da camada de visão se
distanciando da camada modelo a qual possui um observador direto da camada de
visão (SYROMIATNIKOV; WEYNS, 2014).

Figura 25 - Representação gráfica do padrão MVP

Fonte: (SYROMIATNIKOV; WEYNS, 2014)

2.10.2 Inversão De Controle


De acordo com Fowler (2005) o termo foi provavelmente criado por Johnson e
Foote no artigo “Designing Reusable Classes” de 1988.
Segundo Kumar (2019) Inversão de Controle (IoC) é um princípio de
desenvolvimento cujas implementações podem ser feitas através de vários padrões
de projeto. Ele cita alguns: Injeção de Dependência, Estratégia, Localizador de
Serviço.

[Inversão de controle] envolve reverter o fluxo de controle usual, partindo do


código chamador para o chamado, alcançando melhor separação semântica
e baixa acoplagem. Isso permite construir aplicativos sofisticados enquanto
mantém a complexidade geral do projeto em um nível gerenciável.
(ROBILLARD, 2019, p. 191).
47

Para Fowler (2004) “é uma característica comum de frameworks, então dizer


que esses contêineres leves são especiais porque usam inversão de controle é como
dizer que meu carro é especial porque tem rodas”.
Robillard (2019, p. 192-3) diz que uma motivação concreta está na necessidade
de se manter consistência em objetos de estado. Ele cita um projeto ultrapassado
“Pares de Dependências Sábias” a qual cada componente possui como dependência
todos os outros criando uma cascata quadrática de requisições de dependência para
cada componente que precise realizar mudança de estado.

2.10.2.1 Injeção De Dependência


Segundo Fowler (2004), “a ideia básica da injeção de dependência é ter um
objeto separado, um montador, que preenche um campo na classe de listagem com
uma implementação apropriada para a interface do localizador.”

Figura 26 - Representação gráfica de Injeção de Dependência

Fonte: (FOWLER, 2004)

Fowler (2004) subdivide Injeção de Dependência (DI) em três “estilos”


diferentes, são eles: injeção no construtor, injeção por método (setter injection) e
injeção pela interface.
48

Deursen e Seemann (2019) dizem que o principal objetivo da DI é permitir baixa


acoplagem e que isso torna o código com melhor mantenibilidade.
Deursen e Seemann (2019) fazem uma lista de benefícios, abaixo estão
alguns:
● Facilmente adaptável a mudanças de requisitos imprevistas;
● Permite vinculação tardia;
● Facilita estender e reusar código de maneiras não planejadas;
● Facilita testes unitários;
Classes não devem pedir a terceiros suas dependências, mas usar injeção no
construtor;
● Para ter sucesso, você precisa aplicar o DI de forma abrangente.

2.11 História IOT


O próprio conceito de dispositivos conectados remonta a 1832, quando o
primeiro telégrafo eletromagnético foi projetado. O telégrafo possibilitou a
comunicação direta entre duas máquinas por meio da transferência de sinais elétricos.
No entanto, a verdadeira história da IoT começou com a invenção da Internet - um
componente essencial - no final dos anos 1960, que se desenvolveu rapidamente nas
décadas seguintes. (TEIXEIRA, 2018)
Em 1980, o primeiro dispositivo conectado foi uma máquina de venda
automática da Coca-Cola situada na Carnegie Melon University e operada por
programadores locais. Eles integraram microinterruptores à máquina e usaram uma
forma inicial de internet para ver se o dispositivo de resfriamento estava mantendo as
bebidas frias o suficiente e se havia latas de Coca disponíveis. Esta invenção
fomentou mais estudos na área e o desenvolvimento de máquinas interconectadas
em todo o mundo. (SANTOS, 2018)
Em 1990, John Romkey conectou uma torradeira à Internet pela primeira vez
com um protocolo TCP / IP. Um ano depois, os cientistas da Universidade de
Cambridge tiveram a ideia de usar o primeiro protótipo de câmera da web para
monitorar a quantidade de café disponível na cafeteira de seu laboratório de
informática local. Eles programaram a webcam para tirar fotos da cafeteira três vezes
por minuto, depois enviaram as imagens para os computadores locais, permitindo que
todos vissem se havia café disponível. (SANTOS, 2018)
49

O termo Internet das Coisas (Internet of Things) tem por volta de 22 anos. Mas
a ideia real de dispositivos conectados já existia há mais tempo, pelo menos desde os
anos 70. Naquela época, a ideia era frequentemente chamada de “internet
incorporada” ou “computação pervasiva”. Mas o termo real “Internet das Coisas” foi
criado por Kevin Ashton em 1999 durante seu trabalho na Procter & Gamble. Ashton,
que trabalhava na otimização da cadeia de suprimentos, queria atrair a atenção da
gerência sênior para uma nova tecnologia interessante chamada RFID. Como a
internet era a nova tendência mais quente em 1999 e de alguma forma fazia sentido,
ele chamou sua apresentação de “Internet das Coisas”. Embora Kevin tenha
despertado o interesse de alguns executivos da P&G, o termo Internet das Coisas não
recebeu grande atenção nos 10 anos seguintes. (SANTOS, 2018)
Segundo Neil Gross, no próximo século, o planeta Terra vestirá uma “pele”
eletrônica. Ele usará a Internet como um andaime para apoiar e transmitir suas
sensações. Essa pele já está sendo costurada. É composta por milhões de
dispositivos de medição eletrônicos embutidos: termostatos, medidores de pressão,
detectores de poluição, câmeras, microfones, sensores de glicose, EKGs,
eletroencefalógrafos. Eles sondarão e monitorarão cidades e espécies ameaçadas de
extinção, a atmosfera, nossos navios, rodovias e frotas de caminhões, nossas
conversas, nossos corpos - até mesmo nossos sonhos. (GROSS, 1999)
No ano de 2013, a Internet das Coisas evoluiu para um sistema que usa várias
tecnologias, que vão desde a Internet à comunicação sem fio e de sistemas
microeletromecânicos (MEMS) a sistemas embarcados. Os campos tradicionais de
automação (incluindo a automação de edifícios e residências), redes de sensores sem
fio, GPS, sistemas de controle e outros, todos suportam a IoT. Em termos simples, a
Internet das Coisas consiste em qualquer dispositivo com um botão liga / desliga
conectado à Internet. Isso inclui quase tudo que você possa imaginar, desde telefones
celulares até manutenção de prédios e motores a jato de um avião. (TEIXEIRA, 2018)
Os Dispositivos médicos, pode ajudar com um implante de monitor cardíaco ou
um transponder biochip em um animal de fazenda, podem transferir dados por meio
de uma rede e são membros da IoT. Se tiver um botão liga / desliga, pode,
teoricamente, fazer parte do sistema. A IoT consiste em uma rede gigantesca de
“coisas” e dispositivos conectados à Internet. Ring, uma campainha com link para seu
smartphone, é um excelente exemplo de uma adição recente à Internet das Coisas.
50

O toque avisa quando a campainha é pressionada e permite que você veja quem é e
fale com eles. (TEIXEIRA, 2018)

2.12 Segurança IOT


Segurança IoT é o ato de proteger os dispositivos da Internet das Coisas e as
redes às quais eles estão conectados. No ambiente empresarial, os dispositivos IoT
incluem máquinas industriais, redes de energia inteligentes, automação predial, além
de quaisquer dispositivos IoT pessoais que os funcionários tragam para o trabalho.
(FUKUDA, 2019)
As ferramentas de segurança da IoT protegem contra ameaças e violações,
identificam e monitoram riscos e podem ajudar a corrigir vulnerabilidades. A
segurança de IoT garante a disponibilidade, integridade e confidencialidade de sua
solução de IoT. (FUKUDA, 2019)
Desde o aumento da segurança em estradas, carros e residências até a
melhoria fundamental da maneira como fabricamos e consumimos produtos, as
soluções de IoT fornecem dados e percepções valiosas que aprimorarão a maneira
como trabalhamos e vivemos. O sucesso depende de garantir a integridade e a
confidencialidade das soluções e dados de IoT, ao mesmo tempo que reduz os riscos
de segurança cibernética. (FUKUDA, 2019)
Embora haja medidas a serem seguidas para ajudar a garantir a segurança,
não deve ser surpresa que esse problema tenha se tornado uma preocupação
significativa com o crescimento da IoT. Literalmente, bilhões de dispositivos estão
sendo interconectados, tornando possível (eventualmente) que alguém invada sua
cafeteira e, em seguida, acesse sua rede inteira. A Internet das Coisas também torna
as empresas em todo o mundo mais abertas às ameaças à segurança. Além disso, o
compartilhamento de dados e a privacidade tornam-se problemas ao usar a Internet
das Coisas. Considere como as preocupações aumentarão quando bilhões de
dispositivos estiverem interconectados. Algumas empresas enfrentarão o
armazenamento de grandes quantidades de informações que esses dispositivos
produzirão. Eles precisarão encontrar um método de armazenar os dados com
segurança, ao mesmo tempo em que conseguem acessar, rastrear e analisar a grande
quantidade de dados que está sendo gerada. (PEPINO, 2018)
51

Máquinas e objetos em praticamente qualquer setor podem ser conectados e


configurados para enviar dados por redes celulares para aplicativos em nuvem e back-
ends. O risco de segurança digital está presente em cada etapa da jornada da IoT, e
há um monte de hackers que tirariam proveito da vulnerabilidade de um sistema.
Infelizmente, diversos tipos de dados e poder de computação entre os dispositivos de
IoT significam que não existe uma solução de segurança cibernética 'tamanho único'
que possa proteger qualquer implantação de IoT. A primeira etapa para qualquer
negócio de IoT é passar por uma avaliação de risco de segurança completa que
examina vulnerabilidades em dispositivos e sistemas de rede e sistemas de back-end
de usuários e clientes. O risco deve ser mitigado em todo o ciclo de vida da IoT da
implantação, especialmente à medida que ela se expande e se expande
geograficamente. (JUNIOR, 2018)
James Lewis, que é pesquisador de segurança cibernética do Centro de
Estudos Estratégicos e Internacionais, escreveu um relatório descrevendo como as
interconexões da Internet das Coisas permitirão que hackers de computador causem
estragos por meio de dispositivos interconectados. A ameaça é tão real que até a
Federal Trade Commission se envolveu, querendo saber como garantir a privacidade
e como as proteções de segurança estão sendo instaladas em novos dispositivos
conectados à Internet. Por exemplo, carros novos agora podem ser sequestrados por
meio de suas conexões WI-FI. Considere a ameaça de hackers quando a direção
automatizada se tornar popular. O gerenciamento de segurança e risco não deve ser
considerado ao criar maneiras de usar a Internet das Coisas. (JUNIOR, 2018)

3 COMPOSIÇÃO DO PROJETO
3.1 Ferramentas
3.1.1 Ec2 (aws)
Uma instância EC2 é um servidor virtual no Elastic Compute Cloud (EC2) da
Amazon para a execução de aplicativos na infraestrutura Amazon Web Services
(AWS). AWS é uma plataforma de computação em nuvem abrangente e em evolução;
EC2 é um serviço que permite que assinantes comerciais executem programas de
aplicativos no ambiente de computação. Ele pode servir como um conjunto
praticamente ilimitado de máquinas virtuais (VMs). (AWS Amazon)
52

A Amazon oferece vários tipos de instâncias com diferentes configurações de


CPU, memória, armazenamento e recursos de rede para atender às necessidades do
usuário. Cada tipo está disponível em vários tamanhos para atender a requisitos
específicos de carga de trabalho. (AWS Amazon)
As instâncias são criadas a partir de Amazon Machine Images (AMI). As
imagens da máquina são como modelos. Eles são configurados com um sistema
operacional (SO) e outro software, que determina o ambiente operacional do usuário.
Os usuários podem selecionar um AMI fornecido pela AWS, a comunidade de usuários
ou por meio do AWS Marketplace. Os usuários também podem criar seus próprios
AMIs e compartilhá-los. (AWS Amazon)
EC2 é o principal componente de computação da pilha de tecnologia. Na
prática, o EC2 facilita a vida dos desenvolvedores ao fornecer capacidade de
computação segura e redimensionável na nuvem. Facilita muito o processo de
ampliação ou redução, pode ser integrado a vários outros serviços. Algumas das
principais características: não precisar de nenhuma unidade de hardware e facilmente
escalável. (AWS Amazon)

3.1.2 IDE (Eclipse)


Em novembro de 2001, a IBM criou o Projeto Eclipse para implementar um IDE
baseado em Java que oferece suporte ao desenvolvimento de aplicativos Java
incorporados. A versão inicial do Eclipse deriva do Visual Age - um IDE de linguagem
de multiprogramação da IBM. (Cortes)
Em janeiro de 2004, a Eclipse Foundation foi estabelecida como uma
corporação independente sem fins lucrativos para desenvolver de forma transparente
o Projeto Eclipse como um produto aberto e independente de fornecedor. (Cortes)
Originalmente criado para desenvolver um IDE Java, a Eclipse Foundation
agora está desenvolvendo uma ampla gama de ferramentas de desenvolvimento que
suportam muitas linguagens de programação: C, C++, PHP, Javascript, Python, Rust
e etc. No entanto, o Eclipse é mais conhecido como o IDE mais usado para
Desenvolvimento Java. O Eclipse é gratuito e de código aberto, o que significa que se
pode usá-lo sem nenhum custo e acessar seu código-fonte, se necessário.
(DEVMEDIA)
53

Ele conquistou o mercado em torno de 65%, já que a plataforma é líder em


ambiente de desenvolvimento baseado em java. É usado porque fornece a
funcionalidade de adicionar vários componentes diferentes na plataforma que são
conhecidos como plug-ins. Diferentes tipos de organização de TI preferem o IDE
Eclipse por causa dessa funcionalidade. A plataforma oferece soluções empacotadas
para que o desenvolvedor possa usar os pacotes durante a fase de desenvolvimento.
(Cortes)
O processo de instalação do Eclipse IDE é comparativamente fácil para outro
IDE. O usuário pode fazer download do pacote pré-empacotado para que faça
download e instale diretamente o eclipse para fins de programação. (Cortes)
Também é usado por causa da interface de usuário simplificada na qual o
usuário pode codificar facilmente e desenvolver o aplicativo de recursos avançados.
O espaço de trabalho é fornecido pela plataforma na qual o usuário pode empacotar
todos os projetos em um único espaço de trabalho. (Cortes)

3.1.3 Spring
O Spring é um framework Java, criado com o objetivo de facilitar o
desenvolvimento de aplicações. (TREINAWEB)
O Spring é um framework de código aberto criado por Rod Johnson. Foi criado
para lidar com a complexidade de desenvolvimento de aplicativos corporativos. O
Spring torna possível usar simples JavaBeans para conseguir coisas que só eram
possíveis com EJBs. Porém, a utilidade do Spring não é limitada ao desenvolvimento
do lado servidor. Qualquer aplicativo Java pode se beneficiar do Spring em termos de
simplicidade, testabilidade e baixo acoplamento. Spring fornece muitas
funcionalidades de estrutura como gerenciamento de transações, integração de
frameworks de persistências de objetos, e é considerado um container que gerencia
o ciclo de vida e a configuração de objetos do aplicativo. (TREINAWEB)
A utilização do Spring traz um ganho considerável com relação a qualidade de
software em termos de design patterns. (TREINAWEB)

3.1.4 Maven (gerenciador de dependência)


Maven é uma ferramenta popular de construção de código aberto desenvolvida
pela “Apache Group” para construir, publicar e implantar vários projetos de uma vez
54

para um melhor gerenciamento de projetos. A ferramenta permite que os


desenvolvedores criem e documentem a estrutura do ciclo de vida. (ALURA)
Devido ao seu forte apoio e imensa popularidade, o Maven é muito estável e
rico em recursos, fornecendo vários plug-ins que podem fazer qualquer coisa, desde
gerar versões em PDF da documentação do projeto até gerar uma lista de alterações
recentes do SCM. E tudo o que é necessário para adicionar essa funcionalidade é
uma pequena quantidade de XML extra ou um parâmetro de linha de comando extra.
(ALURA)
Maven é uma ferramenta poderosa de gerenciamento de projeto que se baseia
no POM (modelo de objeto de projeto). (ALURA)

3.1.5 Bootstrap (framework para CSS)


Bootstrap é uma estrutura HTML, CSS e JavaScript mais popular de
desenvolvimento de front-end de código aberto para a criação de sites e aplicativos
da web. É utilizado para um desenvolvimento web mais fácil e rápido e totalmente
gratuito para baixar e usar. (HOSTINGER)
Inclui modelos de design baseados em HTML e CSS para tipografia,
formulários, botões, tabelas, navegação, modais, carrosséis de imagens e muitos
outros, com a possibilidade de usar plug-ins de JavaScript, facilitando a criação de
designs responsivos. (HOSTINGER)

3.1.6 Postman
Postman é um aplicativo usado para teste de API. É um cliente HTTP que testa
requisições HTTP, utilizando uma interface gráfica de usuário, através da qual
obtemos diferentes tipos de respostas que precisam ser posteriormente validadas.
Torna mais fácil para os desenvolvedores criar, compartilhar, testar e documentar
APIs. Isso é feito permitindo que os usuários criem e salvem solicitações HTTP’s
simples e complexas, bem como leiam suas respostas. (CIELO)
Postman oferece a possibilidade de agrupar diferentes pedidos. Esse recurso
é conhecido como ‘coleções’ e ajuda a organizar os testes. (CIELO)
Essas coleções são pastas onde as solicitações são armazenadas e podem ser
estruturadas da maneira que a equipe preferir. Também é possível exportar-importar.
55

Postman também nos permite criar ambientes diferentes através da


geração/uso de variáveis; por exemplo, uma variável de URL que se destina a
diferentes ambientes de teste (DEV-QA), permitindo-nos executar testes em
diferentes ambientes usando solicitações existentes. (CIELO)

3.1.7 Git
Git é um sistema de controle de versão distribuída de código aberto. É uma
ferramenta DevOps usada para gerenciamento de código-fonte. É um sistema de
controle de versão gratuito e de código aberto usado para lidar com projetos pequenos
a muito grandes com eficiência. Git é usado para rastrear alterações no código-fonte,
permitindo que vários desenvolvedores trabalhem juntos no desenvolvimento não
linear. (BETRYBE)
Pode ser um sistema de controle, significa que o Git é um rastreador de
conteúdo. Portanto, o Git pode ser usado para armazenar conteúdo - ele é usado
principalmente para armazenar código devido aos outros recursos que fornece.
(BETRYBE)
Também pode ser um sistema de controle de versão, o código armazenado no
Git muda continuamente à medida que mais código é adicionado. Além disso, muitos
desenvolvedores podem adicionar código em paralelo. Portanto, o Sistema de
Controle de Versão ajuda a lidar com isso, mantendo um histórico das mudanças que
aconteceram. Além disso, o Git fornece recursos como branches e merges, que
abordarei mais tarde. (BETRYBE)
E por fim, pode ser um sistema de controle de versão distribuída, o Git possui
um repositório remoto que fica armazenado em um servidor e um repositório local que
fica armazenado no computador de cada desenvolvedor. Isso significa que o código
não é apenas armazenado em um servidor central, mas a cópia completa do código
está presente em todos os computadores dos desenvolvedores. (BETRYBE)

3.1.8 Github
GitHub é uma interface baseada na web que usa Git, o software de controle de
versão de código aberto que permite que várias pessoas façam alterações separadas
em páginas da web ao mesmo tempo. Incentiva as equipes a trabalharem juntas para
construir e editar o conteúdo do site. (HOSTINGER)
56

GitHub é um serviço de hospedagem de repositório Git, mas adiciona muitos


de seus próprios recursos. Enquanto Git é uma ferramenta de linha de comando,
GitHub fornece uma interface gráfica baseada na web. Ele também fornece controle
de acesso e vários recursos de colaboração, como wikis e ferramentas básicas de
gerenciamento de tarefas para cada projeto. (HOSTINGER)
A principal funcionalidade do GitHub é “bifurcação” - copiar um repositório da
conta de um usuário para outra. Isso permite que você pegue um projeto ao qual não
tenha acesso de gravação e modifique-o em sua própria conta. Se você fizer
alterações que gostaria de compartilhar, poderá enviar uma notificação ao proprietário
original. Esse usuário pode então, com um clique de botão, mesclar as alterações
encontradas em seu repositório com o repositório original. Quanto mais pessoas e
projetos no GitHub, melhor imagem o “criador” do projeto pode ter de contribuidores
em potencial, tornando o gerenciamento de contribuições mais fácil. (HOSTINGER)

3.1.9 Fritzing
Fritzing é um simulador de circuitos eletrônicos digitais com iniciativa de
hardware de código aberto que torna a eletrônica acessível como um material criativo.
Este software permite que sejam criados layouts de circuitos eletrônicos de maneira
simples e rápida. Estes layouts permitem a documentação dos esquemáticos por
pesquisadores, designers, artistas e hobbistas. (Fritizing)
O Fritzing foi utilizado para implantação do sistema, que permitiu a montagem,
prototipação e visualização dos componentes antes mesmo de ser construído o
circuito físico, garantindo maior segurança e direcionamento para prototipação.

3.1.10 IDE Arduino


IDE do Arduino é um ambiente de desenvolvimento integrado. Este software é
um editor de texto que possibilita toda a estruturação do código e o upload para a
placa controladora correspondente.
A sintaxe da linguagem Arduino é derivada do Wiring e foi desenvolvido por
Hernando Barragan, é basicamente C/C++, possui funções simples e específicas para
trabalhar com as portas do Arduino. É necessárias duas funções elementares para
seu funcionamento: setup () e loop () (ARDUINO, 2016).
57

3.2 Materiais
3.2.1 Arduino
Dentre as várias opções de modelos da placa open source, foi escolhido o
modelo Arduino Nano por ser uma placa controladora de pequenas dimensões,
específica para atender a proposta do projeto de ser um dispositivo discreto.
Pela razão acima que se deu fundamentalmente o uso do Arduino Nano mas
além disso, a sua acessibilidade e a facilidade que se tem ao utilizar sua IDE para a
programação foi um fator de peso para sua aplicação.

Figura 27 - Arduino Nano

Fonte: Autoria Própria (2021)

O Arduino possui uma grande gama de componentes a serem utilizados, desde


botões a LED’s, sensores a resistores e dentre outros, contribuindo para as mais
variadas configurações fazendo com que o projeto represente um certo grau de
dificuldade, mas também possuir versatilidade tendo mais alternativas para
incrementar o protótipo.
É possível construir diversos projetos através do Arduino e seus componentes,
servindo para essencialmente quaisquer que sejam os objetivos do trabalho, além de
ser código aberto.
As principais características desta placa são:
8 entradas analógicas portas: a0 aa7
14 portas de entrada/saída digitais: tx, rx, d2 dd13
6 portas pwm: d3, d5, d6, d9, d10, d11
1 pares de portas de série rx/tx do transceptor do nível de ttl
Microcontrolador Atmega328P-AU
58

3.2.2 Módulo Gprs Gsm


O Módulo SIM800C é utilizado para comunicação via dados GSM/ GPRS, com
a primordialidade de um chip de operadora de telefonia móvel qualquer para
comunicação, o módulo pode ter suas ações controladas por uma placa controladora
como o Arduino por exemplo.

Figura 28 - Módulo Gprs Gsm

Fonte: Autoria Própria (2021)

Esse módulo foi escolhido para ser conectado no Arduino, com o intuito de
inserir um chip de operadora de telefonia móvel, com a necessidade de obter sinal de
internet e transmitir os dados de localização para a aplicação com uma possibilidade
maior de sempre manter o componente conectado com a internet.
Características gerais

• Quad-band 850/900/1800/1900 MHz

• GPRS multi-slot classe 12/10

• Estação móvel GPRS classe B

• Compatível com GSM fase 2/2 +

• Classe 4 (2 W @ 850/900 MHz)

• Classe 1 (1 W @ 1800/1900 MHz)

• Dimensões: 17,6 * 15,7 * 2,3 mm

• Peso: 1,3g

• Controle por meio de comandos AT (3GPP TS 27.007, 27.005 e comandos AT


aprimorados do SIMCom)
59

• Faixa de tensão de alimentação 3,4 ~ 4,4V

• Baixo consumo de energia

• Temperatura de operação: -40 ℃ ~ 85 ℃

3.2.3 Placa Protoboard


Foi utilizado como base para a construção do protótipo a placa protoboard. Uma
vez que não é necessária utilização de solda e ser reutilizável é muito utilizada por
alunos na educação tecnológica. Na parte superior há uma base de plástico, no qual
existem centenas de entradas onde os componentes são conectados. Em seu interior,
contatos metálicos são instalados para que os componentes inseridos na placa fiquem
interligados eletricamente, conforme Figura 28:

Figura 29 - Placa Protoboard

Fonte: Autoria Própria (2021)


60

3.2.4 Módulo NodeMCU ESP8266


Figura 30 - NodemCU

Fonte: Autoria Própria (2021)

O módulo NodeMcu ESP-12E é uma placa de desenvolvimento que combina o


chip ESP8266, uma interface usb-serial e um regulador de tensão 3.3V. A
programação pode ser feita usando o “Arduino IDE”, com a comunicação via cabo
micro-usb.
Suas principais características são:
• Padrões wireless: IEEE 802.11b, IEEE 802.11g, IEEE 802.11n;
• - Faixa de frequência: 2.4GHz;
• -Taxa de transmissão: 110 à 460 Mbps;
• Antena Embutida;
• -Interface USB: CH340;
• -Interface: Serial UART (Tx / Rx);
• -Segurança: WEP / WPA / TKIP / AES;
• -Alimentação: 4,0 à 9,0 VDC (conector Micro USB);
• -Tensão Lógica: 3,3 VDC;
• -Consumo: Min 70 mA (Standby) e Máx 220 mA (802.11b, CCK
1Mbps,Pout=+19.5dBm);
• - Conversor A/D: 10 bits ADC e Vin 0 à 1 VDC;
• - GPIO: 11 portas;
• - Dimensão: 6,0 x 3,0 x 1,5 cm (C x L x A);
• - Peso: 10g;
61

3.2.5 Chave Gangorra com 2 Terminais

Figura 31 - Chave Gangorra

Fonte: Autoria Própria (2021)

Chave Gangorra com 2 terminais, é um componente que tem a função de


LIGAR (energizar) / DESLIGAR (desenergizar) cargas, através do acionamento ou
seccionamento da alimentação do circuito elétrico.

3.2.6 L7805C Regulador de Tensão 5V

Figura 32 - L7805C Regulador de Tensão 5V

Fonte: (Autoria Própria (2021)


62

O regulador de tensão 7805 pode ser usado em fontes de alimentação,


carregadores e circuitos em geral, fornecendo uma tensão fixa de 5V na saída.

3.2.7 Suporte para 2 Baterias

Figura 33 - Suporte para 2 Baterias

Fonte: Autoria Própria (2021)

O Suporte para 2 Baterias, ideal para construção do projeto eletrônico


alimentado por pilhas, oferecendo o melhor acabamento e visual.

3.2.8 Bateria Recarregável 18650 4.2V Li-ion Lítio

Figura 34 - Bateria Recarregável 18650 4.2V Li-ion Lítio

Fonte: Autoria Própria (2021)


63

Duas baterias recarregável 4,2V 18650 opção de energia ideal para


alimentação do projeto eletrônico.
Especificações Técnicas:
• Produto: Bateria Recarregável 4,2V 18650 Li-ion Lítio
• Modelo: 18650
• Marca: OEM
• Tipo: Li-Ion
• Tensão: 4,2V
• Capacidade Nominal: 880mAh
• Ponto de proteção de sobrecarga: 4,2v
• Ponto de proteção de descarga: 2,75v
• Carga padrão: 10 horas
• Carga rápida: 2.5 horas
• Dimensões: 18mm de diâmetro x 67mm de comprimento
• Material: Termoplásticos/Metal
• Origem: China
• Tamanho: 18mm Largura x 67mm Profundidade x 18mm Altura
• Peso: 30g

3.3 Construção do hardware


Com os itens mencionados no tópico anterior, foi realizado toda a construção
do protótipo que pode ser descrito como uma peça única, móvel e de fácil utilização.
O protótipo virtual (Figura 34), foi de suma importância durante a fase inicial do
desenvolvimento, facilitando a realização de testes de forma rápida com o auxílio da
ferramenta Fritzing. Havendo todo mapeamento em mãos, o projeto teve a etapa
inicial concluída, partindo para o desenvolvimento do protótipo físico.
64

Figura 35 - Protótipo virtual

Fonte: Autoria Própria (2021)

O protótipo é composto por cinco componentes, onde a placa controladora


integrada com o módulo do esp8266 é alimentado por uma fonte de alimentação com
7.5V. Dessa forma, foi necessário a utilização do Regulador de Tensão 5V L7805C
para alimentação necessária que a placa requer, sendo ligado o positivo na porta VIN
e o negativo no GND. E por fim foi utilizado uma Chave Gangorra com 2 Terminais,
para ligar/desligar o circuito eletrônico.
65

Figura 36 - Protótipo físico.

Fonte: Autoria Própria (2021)

3.4 Métodos
3.4.1 Construção Do Software
Para atender os requisitos anteriormente apresentados foram modelados dois
diagramas gerais que possuem por objetivo nortear o desenvolvimento futuro do
projeto. São eles os diagramas de casos de uso e o de classe.
66

3.4.2 Diagrama De Casos De Uso


Na figura 1, há a explicitação das principais funções necessárias para atender
os requisitos, funcionais e não funcionais, propostos. Nele também está explicitada a
interação com seus atores (entidades que não pertencem ao software, mas interagem
com o mesmo).

Figura 37 - Diagrama de casos de uso

Fonte: Autoria Própria (2021

Na sequência, seguem-se os nove quadros explicativos que complementam o


entendimento para cada caso de uso do sistema. Eles fornecem informações
importantes como pré-condições e os passos necessários para a execução da
função no sistema.
67

Tabela 1 - Quadro 1: Documentação do caso de uso "Criar cadastro"

Nome do caso de uso Criar cadastro


Ator principal Usuário
Atores secundários
Etapas para usuário se cadastrar na
Resumo
plataforma
Pré-condições Acesso a navegador com internet com o
sistema aberto
Ações ator Ações do sistema
1. Clicar em “Criar cadastro”
2. Exibir tela para criação de cadastro
3. Preencher campos (e-mail e senha)
4. Clicar em criar
5. Executar “Modificar base de dados”
6. Enviar e-mail de confirmação
7. Verificar e-mail
8. Clicar no link fornecido
9. Ativar conta

Fonte: Autoria Própria (2021

Nome do caso de uso Login


Ator principal Usuário
Atores secundários
Etapas para usuário efetuar login na
Resumo
plataforma
Acesso a navegador com internet com
Pré-condições
o sistema aberto
Ações ator Ações do sistema
1. Preencher campos (e-mail/login e
senha)
2. Clicar em login
3. Exibir tela do painel interno da conta
Tabela 2 - Quadro 2: Documentação do caso de uso "Login"
68

Fonte: Autoria Própria (2021

Tabela 3 - Quadro 3: Documentação do caso de uso "Adicionar dispositivo"

Nome do caso de uso Adicionar dispositivo


Ator principal Usuário
Atores secundários
Etapas para usuário adicionar dispositivo
Resumo
na plataforma
Pré-condições Caso de uso “Login”; possuir dispositivo
Ações ator Ações do sistema
1. Clicar em “Adicionar dispositivo”
2. Exibir tela de identificação do dispositivo
3. Fornecer identificação
4. Exibir tela de orientação de manuseio de
dispositivo
5. Seguir instruções
6. Mostrar tela de dispositivo adicionado

Fonte: Autoria Própria (2021

Tabela 4 - Quadro 4: Documentação do caso de uso "Remover dispositivo"

Nome do caso de uso Remover dispositivo


Ator principal Usuário
Atores secundários
Etapas para usuário remover dispositivo da
Resumo
plataforma
Pré-condições Caso de uso “Login”
Ações ator Ações do sistema
1. Clicar em “Dispositivos”
2. Exibir tela de lista de dispositivos
3. Clicar em “Remover dispositivo” na
mesma respectiva linha do dispositivo a ser
removido
4. Exibir notificação de dispositivo removido

Fonte: Autoria Própria (2021


69

Tabela 5 - Quadro 5: Documentação do caso de uso "Deletar cadastro"

Nome do caso de uso Deletar cadastro


Ator principal Usuário
Atores secundários
Etapas para usuário deletar cadastrar na
Resumo
plataforma
Pré-condições Caso de uso “Login”
Ações ator Ações do sistema
1. Clicar em deletar cadastro
2. Enviar e-mail de confirmação
3. Verificar e-mail
4. Clicar no link fornecido
5. Executar “Modificar base de dados”
6. Exibir tela de conta deletada

Fonte: Autoria Própria (2021

Tabela 6 - Quadro 6: Documentação do caso de uso "Notificar alteração"

Nome do caso de uso Notificar alteração


Ator principal Usuário
Atores secundários
Etapas para usuário se cadastrar na
Resumo
plataforma
Pré-condições Caso de uso “Login”; Caso de uso “Receber
Dados”
Ações ator Ações do sistema
1. Exibir dados dos dispositivos

Fonte: Autoria Própria (2021


70

Tabela 7 - Quadro 7: Documentação do caso de uso "Receber Dados"

Nome do caso de uso Receber Dados


Ator principal Dispositivo de rastreio
Atores secundários
Etapas para a plataforma receber dados do
Resumo
dispositivo
Pré-condições Caso de uso “Adicionar dispositivo”
Ações ator Ações do sistema
1. Acessar via post url previamente salva no
dispositivo enviando variáveis com dados
dos sensores
2. Tratar dados
3. Executar “Modificar base de dados”

Fonte: Autoria Própria (2021

Tabela 8 Quadro 8: Documentação do caso de uso "Modificar base de dados"

Nome do caso de uso Modificar base de dados


Ator principal Usuário
Atores secundários Dispositivo de rastreio
Modificação (criação, atualização ou
Resumo
remoção) de dados na plataforma
Pré-condições Ser requisitada por outro caso de uso
Ações ator Ações do sistema
1. Verificar parâmetros recebidos dos
outros casos de usos
2. Executar a modificação de acordo com
os parâmetros

Fonte: Autoria Própria (2021


71

Tabela 9 - Quadro 9: Documentação do caso de uso "Logout"

Nome do caso de uso Logout


Ator principal Usuário
Atores secundários
Etapas para usuário efetuar logout na
Resumo
plataforma
Pré-condições Caso de uso ”Login”
Ações ator Ações do sistema
1. Clicar em “Logout”
2. Mostrar tela de logout

Fonte: Autoria Própria (2021

3.4.3 Diagrama De Classe


Na figura 37, o diagrama de classe se apresenta subdividido em três grupos: O
grupo em verde que representam classes que compõe as entidades e afins dos dados
que serão manipulados pelo software; em azul classes responsáveis pela
manipulação das queries; E, por último, em amarelo classes que contém as
funcionalidades que o software oferta.

Figura 38 - Diagrama de classe se apresenta subdividido em três grupos

Fonte Autoria Própria (2021


72

4 PLANO DE TESTABILIDADE
Os modelos de testes utilizados foram os de caixa branca e de caixa preta,
sendo duas interpelações de testes da aplicação, validando tanto a parte interna da
aplicação (como a codificação por exemplo), quanto a parte externa (como a
perspectiva final do usuário).

4.1 Teste caixa branca


O objetivo proposto para os testes de caixa branca é garantir a qualidade na
implementação do sistema. Logo, o plano para realização dos testes da aplicação foi
definido da seguinte maneira:
Teste de condição: Nessa etapa é planejado realizar toda a avaliação dos
operadores/variáveis lógicos (booleanos – true/false) simples ou compostos para
analisar os desvios possíveis existentes, no qual o teste examina ambos os lados da
condição booleana.
Uma condição encontra-se errada das seguintes formas:
1. Erros de operador booleano;
2. Erros de variáveis booleana;
3. Erros de parêntese booleano;
4. Erros de operador relacional;
5. Erros de expressão aritmética; (PRESSMAN)
Teste de ciclo: Etapa responsável por validar todas as estruturas de repetição.
Dessa forma, essa técnica foi segmentada em quatro tipos para análise: Ciclo
desestruturado, simples, aninhado e concatenado.
Ciclo desestruturado: Sempre que ocorrer este evento deve-se reestruturar o
ciclo para pensar no uso do desenvolvimento da programação estruturada
(PRESSMAN).
Ciclo simples: Realização de teste de um tamanho “n” em uma estrutura de
repetição, de modo que:
• Pule o ciclo completamente;
• Uma passagem pelo ciclo;
• Duas passagens pelo ciclo;
• k passagens pelo ciclo em que k< n.
• n -1 passagens pelo ciclo;
• n +1 passagens pelo ciclo. (BURNSTEIN)
73

Ciclo aninhados: Para esse comportamento testa se os ciclos mais internos


que são aplicados à abordagem de ciclos simples e os outros ciclos externos
permanecem com o valor mínimo. (PRESSMAN)
Ciclos concatenados: Utiliza no ciclo concatenado a abordagem de ciclos
simples para o caso dos ciclos forem independentes um do outro, caso contrário é
recomendado o uso da abordagem de ciclos aninhados. (PRESSMAN).
Teste de funções: É de suma importância garantir o funcionamento das
funções implementadas no desenvolvimento da aplicação. Dessa forma, está etapa é
responsável por toda testabilidade das funções implementadas, garantindo o
comportamento e retorno esperado.

4.2 Teste da caixa preta


Técnica de teste responsável pela testabilidade das funcionalidades dos
comportamentos externos da aplicação, ou seja, o objetivo é garantir que todas as
interações do usuário com o sistema tenham êxito, garantindo o retorno esperado.
Teste da tela de login:
Fase em que será testado a interação do usuário com a tela de login da
aplicação, onde serão avaliados os critérios a seguir:
1. Verificar se o nome de usuário e senha são correspondentes;
2. Indicação que o nome de usuário ou senha estão incorretos;
3. Teste da funcionalidade “Esqueci a senha”;
4. Caso o usuário não for existente, sugestão da criação de conta.
74

Figura 39 - Teste da tela de login

Fonte: Autoria Própria (2021)

Teste da tela de cadastro:


Nessa etapa será testado todos os campos necessários para o cadastro do
usuário para utilização do sistema e retorno dos mesmos, sendo elas:

1. Teste de retorno para quando o usuário já for existente, se sim, qual será a
mensagem de retorno para o usuário;

2. Teste se o e-mail válido;

3. Teste de senha com mais de 8 caracteres;

4. Verifica se os dados inseridos para cadastrar um novo usuário estão corretos;

5. Mensagem de confirmação do cadastramento do novo usuário;


75

Figura 40 - Teste da tela de cadastro

Fonte: autoria própria (2021)

Teste da tela principal:


Fase final onde será testado a interação do usuário com a tela principal, que
terá as principais funcionalidades da aplicação realizando os seguintes testes:
1. Verificação se informações do perfil estão sendo apresentadas de forma
correta;
2. Funcionalidade para adicionar dispositivos (coleira / animal);
3. Testabilidade dos botões, sendo eles, localização do dispositivo/animal, edição
de informações e exclusão de dispositivos.
76

Figura 41 - Teste da tela principal

Fonte: Autoria Própria (2021)

5 TESTES E RESULTADOS
Os testes foram realizados em ambiente fechado, com estrutura e ferramentas
adequadas para evitar qualquer tipo de dano físico, com relação aos participantes e
aos materiais.
Devido a Pandemia do Covid-19, não foi possível que todos os integrantes
estivessem presentes em todos os testes, mas o compromisso na maioria das vezes
foi honrado. Nos momentos em que os testes não foram realizados fisicamente,
utilizamos o Zoom para fazer as validações possíveis.
77

Tabela 10 - Tabela de Testes.

Objetivo Ação Resultado Data Alvo

Validação dos Teste Sem 30/05/21


componentes de sucesso
hardware

Validação dos Teste Sucesso 10/06/21


componentes de
hardware

Teste de mesa (lógica) Teste Sucesso 23/08/21

Validação Teste Sem 14/09/21


sucesso
do protótipo

Validação de interface Teste Sucesso 28/09/21

Validação Teste Sem 07/10/21


Sucesso
do protótipo

Validação de servidor Teste Sem 13/10/21


sucesso

Validação do protótipo Teste Sucesso 26/10/21

Validação do sistema Teste Sem 28/10/21


completo sucesso

Validação de servidor Teste Sem 01/11/21


sucesso

Validação de API Teste Sem 09/11/21


(Google) sucesso

Validação de API Teste Sucesso 11/11/21


(Google), endpoints e
servidor

Validação do sistema Teste Sucesso 18/11/21


completo

Fonte: Autoria Própria, 2021


78

Foram desenvolvidos dois protótipos, no primeiro, os testes realizados com


multímetro validaram a tensão e voltagem.

Figura 42 - Teste de voltagem.

Fonte: Próprio Autor, 2021.

Porém o teste (que seria o final) feito no dia 07/10, realizado com o GSM, houve
uma identificação da operadora que os dados móveis foram utilizados indevidamente,
e o IMEI acabou sendo bloqueado. Esse problema resultou em um atraso parcial na
finalização do protótipo, pois tivemos que buscar novos recursos para recomeçar o
hardware.

Figura 43 - Protótipo versão

Fonte: Próprio Autor, 2021.


79

Os resultados dos testes com o segundo protótipo foram satisfatórios, sendo


validado de diversos lugares e distâncias diferentes sem dificuldades ou empecilhos.
O protótipo funcionou corretamente.

6 CONCLUSÃO
Dada à importância do assunto, o desenvolvimento do presente estudo
possibilitou uma análise de como a junção de um software e um hardware podem
melhorar a capacidade de localizar imediatamente seu animal de estimação no caso
de ele se afastar de você ou se perder, além de poder economizar nos custos pela
procura do animal. Nesse sentido, a utilização de recursos digitais é muito importante
para evitar complicações com os pets e até para soluções pensando nas piores
possibilidades, visto que essas situações influenciam diretamente nos sentimentos e
nos comportamentos dos seres humanos, além de preservar o bem-estar dos animais.
O sistema tratado neste trabalho tem como objetivo priorizar a segurança de
animais usando a tecnologia para auxiliar nessa difícil missão, tendo em vista a
quantidade alta de animais que acabam se perdendo de seus donos ou que são
roubados em alguns casos. já que a maioria das pessoas tem uma relação sentimental
muito forte com seus animais, e qualquer coisa que possa acontecer com eles, pode
acabar afetando na vida daquela pessoa, então se for possível, é necessário tentar
evitar a perca desses animais de estimação, para que as pessoas tenham uma
expectativa de qualidade de vida melhor, juntos com os seus animais.
Além disso, o dispositivo de rastreio apresenta o desenvolvimento de um
sistema de geolocalização que acompanha a localização dos animais de estimação,
e traz o objetivo de localizar o animal, através de um dispositivo em que o protótipo foi
segmentado em duas partes, que engloba o Arduino em sua composição de hardware
e Software que engloba linguagem Java, em que contribuiu na construção do sistema
para localizar os animais. Nessa situação, a aplicação utilizada por diversos
conhecimentos sendo eles teóricos e tecnológicos obtidos no curso de ciência da
computação, trouxe também para o projeto uma experiencia bastante satisfatória,
para a equipe envolvida, e as diferentes disciplinas que estudamos como modelagem
de dados, programação, banco de dados e engenharia de software, contribuiu em
diversos pontos da construção protótipo.
80

Os requisitos do sistema, começam geralmente com o processo de


desenvolvimento, e para elaboração dos requisitos, foram modelados dois diagramas
gerais, o diagrama de casos de uso, e o diagrama de classe, que possuem por objetivo
nortear o desenvolvimento futuro do projeto. E com a elaboração da modelagem, foi
construído uma lógica, para que o seu desenvolvimento pudesse alcançar os objetivos
do projeto.
E uns dos fatores importantes do projeto, foram os testes dos modelos da caixa
branca e de caixa preta, que contribuíram em diversos fatores da aplicação, os testes
foram realizados com a estrutura e ferramentas adequadas para evitar qualquer tipo
de danos físicos aos materiais e possibilitar concluir os objetivos dos testes do
protótipo.
Portanto, o protótipo completo tem como finalidade ajudar as pessoas que
sofrem com os problemas apresentados, e demonstrar todos os passos que foram
tomados cuidadosamente para entregar a melhor versão possível, sempre de forma
transparente desde o brainstorms sobre o tema, seguindo da parte de planejamento,
passando para a parte de desenvolvimento e testes, até o momento da conclusão do
sistema como um todo.
81

7 REFERÊNCIA BIBLIOGRÁFICA

ABRAHAMSSON, Pekka;OUTI, Salo; RONKAINEN, Jussi; WARSTA, Juhani. Agile


Software Development Methods: Review and Analysis. JTT. Pub 478,
Espoo,2002.https://www.vttresearch.com/sites/default/files/pdf/publications/2002/P
478.pdf

ALLEN, Daniel; Peacock, Adam; Arathoon, Jamie. Spatialities of Dog Theft: A Critical
Perspective. Animals, v. 9, n. 5, p. 209. https://doi.org/10.3390/ani9050209

ALMEIDA, Hugo Leonardo Nascimento. Gestão e planejamento de projetos de


software com scrum. Revista Científica Multidisciplinar Núcleo do Conhecimento.
Ano 04, Ed.03, Vol. 09, p. 114-123. Março de 2019. ISSN: 2448-0959.

ALURA. Maven: Gerenciamento de dependências e build de aplicações Java.


Disponível em: https://www.alura.com.br/conteudo/maven-gerenciamento-
dependencias-build-aplicacoes-java. Acesso em: 30 de outubro de 2021

Amazon EC2. AWS Amazon. Disponível em:https://aws.amazon.com/pt/ec2/?ec2-


whats-new.sort-by=item.additionalFields.postDateTime&ec2-whats-new.sort
order=desc. Acessoem: 28 de outubro de 2021.

BETRYBE. Git: o que é, para que serve e principais comandos Git. Disponível em: <
https://blog.betrybe.com/git/>. Acesso em: 31 de outubro de 2021

BOOCH, Grady; RUMBAUGH, James; JACOBSON, Ivar. The Unified Modeling


LanguageUser Guide. Tradução Fábio Freitas da Silva e Cristina de Amorim Machado.
Ed 2, 2006

CIELO. Postman Cielo Disponível em: https://developercielo.github.io/tutorial/


postman. Acesso em: 30 de outubro de 2021
82

CORTES, Andrea. IDE Eclipse: o que é e sua importância para desenvolvedores.


Remessa Online, 2021. Disponível em: https://www.remessaonline.com.br/blog/ide-
eclipse/. Acesso em: 28 de outubro de 2021.

DEVMEDIA. Conhecendo o Eclipse - Uma apresentação detalhada da IDE.


Disponívelem: https://www.devmedia.com.br/conhecendo-o-eclipse-uma-
apresentacao-detalhada- da-ide/25589 . Acesso em: 30 de outubro de 2021

FARIA, Thiago; AFONSO, Alexandre. JPA - Guia Definitivo. ed. 2, 2020. Disponível
em:http://alga.works/livro-jpa

FOWLER, Martin. Inversion of Control Containers and the Dependency Injection


Pattern.2004. Disponível em https://martinfowler.com/articles/injection.html. Último
acesso em: 28 maio 2021

FOWLER, Martin. Inversion of Control. 2005. Disponível em https://martinfowler.com/


bliki/inversionofcontrol.html. Último acesso em: 28 maio 2021

FUKUDA, Leonardo Massami. Segurança da informação em IOT. 2019. Trabalho de


Conclusão de Curso (Especialização em Gestão da Tecnologia da Informação e
Comunicação) - Universidade Tecnológica Federal do Paraná, Curitiba, 2019.
Disponívelem: http://repositorio.utfpr.edu.br/jspui/handle/1/19442

GRIEGER, A. S.; PINHEIRO, L. C.; FERNANDES, R. F.; SCHUTZ, S. M.; DIAS, I. A.


WebMaps no Auxílio da Busca de Animais: Geopet. Cadernos de iniciação
científica, [s. l.], v. 3, n. 2, 2019. Disponível em: https://cesuscvirtual.com.br/
index.php/CICCESUSC/ article/view/340.

GROSS, Neil. 14: The Earth Will Don an Electronic Skin. 1999. Bloomberg.
Disponível em: https://www.bloomberg.com/news/articles/1999-08-29/14-the-
earth-will-don-an-electronic-skin. Último acesso: 26 de maio de 2021
83

HOSTINGER. O Que é Bootstrap? Guia para Iniciantes. Disponível em:


https://www.hostinger.com.br/tutoriais/o-que-e-bootstrap. Acesso em: 30 de
outubro de2021

HOSTINGER. O Que é GitHub e Como Usá-lo. Disponível em:


https://www.hostinger.com.br/tutoriais/o-que-github. Acesso em: 31 de outubro de
2021

HUSSAIN, Shahid; KEUNG, Jacky; KHAN, Arif. The Effect of Gang-of-Four


Design Patterns Usage on Design Quality Attributes. 2017, p. 263-273.
10.1109/QRS.2017.37.

JUNIOR, Nelson G. Prates; PELLOSO, Mateus; Macedo, Ricardo T.; NOGUEIRA,


Michele. Ameaças de Segurança, Defesas e Análise de Dados em IoT Baseada em
SDN.2018.https://www.inf.ufpr.br/aldri/disc/INFO7015Minicurso_Redes_SDN_SBSe
g2018.pdf

KRASNER, Glenn; POPE, Stephen. A Cookbook for Using View-Controller


User the ModelInterface Paradigm in Smalltalk-80. JOOP - Journal of
Object-Oriented Programming. Aug./Set. 1988. Disponível em:
https://www.ics.uci.edu/~redmiles/ics227-SQ04/papers/KrasnerPope88.pdf

KUMAR, Amit. Understanding Inversion of Control (IoC) Principle. 2019.


Disponível em https://medium.com/@amitkma/understanding-inversion-of-
control-ioc-principle- 163b1dc97454. Último acesso em: 28 maio 2021

KUMAR, Santosh; SINGH, Sanjay K. Monitoring of pet animal in smart cities using
animal biometrics. Future Generation Computer Systems, v. 83, p. 553-563, jun.
2018.

MATHER, Tim; KUMARASWAMY, Subra; lLATIF, SHAHED. Cloud Security and


Privacy.O'Reilly Media, Inc. 2009. ISBN: 9780596802769
84

PACHECO, Diego. Spring Framework (2.0) Framework para


Desenvolvimento de Aplicações em Java. 2007. Disponível em:
https://docplayer.com.br/903622-Spring-framework-2-0-framework-para-
desenvolvimento-de-aplicacoes-em-java.html

PEPINO, Christian Becker; Dias, Guilherme. Pocket guard: dispositivo portátil de


segurança IoT. 2018. Disponível em: http://repositorio.roca.utfpr.edu.br/jspui/
/1/10127

Martin P. Robillard. Introduction to Software Design with Java. Springer, Ago.,


2019.https://doi.org/10.1007/978-3-030-24094-3

SINTES, Anthony. Object Oriented Programming in 21 Days. Tradução João Eduardo


Nóbrega Tortello. Person Education do Brasil. ISBN: 978-8534614610

STORER, Rhi. Stolen dogs in mugshot line-up as police try to locate owners.
2021. Disponível em: https://www.theguardian.com/uk-news/2021/apr/20/stolen-
dogs-in-uk- mugshot-line-up-as-police-try-to-locate-owners. Acesso em: 23 de abril
de 2021.

SYROMIATNIKOV, Artem; WEYNS, Danny. A Journey through the Land of Model-


View- Design Patterns. In:IEEE/IFIP Conference on Software Architecture, 2014,
Sydney, NSW,Australia: IEEE. https://doi.org/10.1109/WICSA.2014.13

PATRICIO, T. S.; TEIXEIRA, M.; MAGNONI, M. da G. M.; BELDA, F. R. INTERNET


DAS COISAS (IOT): AS CONSEQUÊNCIAS DA COMPUTAÇÃO UBÍQUA NA
SOCIEDADE.

Colloquium Humanarum. ISSN: 1809-8207, [S. l.], v. 15, n. 1, p. 83–93, 2018.


Disponível em: https://journal.unoeste.br/index.php/ch/article/view/2323. Acesso em:
26 mai. 2021
85

TOZZI, Tatiana; ANDERLE, Daniel Fernando; NOGUEIRA, Rodrigo Ramos.


Levantamentode Tecnologias para ONGs de Proteção Animal para apoio ao resgate
de animais domésticos acoplados ao ciclo de vida de um sistema Web. In:
WORKSHOP DE TRABALHOS DE INICIAÇÃO CIENTÍFICA - SIMPÓSIO
BRASILEIRO DE SISTEMAS MULTIMÍDIA E WEB (WEBMEDIA), 24. , 2018, Salvador.
Anais [...]. Porto Alegre:Sociedade Brasileira de Computação, 2018 . p. 81-84. ISSN
2596-1683. DOI: https://doi.org/10.5753/webmedia.2018.4574.

TREINAWEB. O que é o Spring?. Disponível em: https://www.treinaweb.com.br/


blog o-que-e-o-spring. Acesso em: 30 de outubro de 2021

TRIVIÑOS, Augusto Nibaldo Silva. Introdução à pesquisa em ciência sociais.


EditoraAtlas S.A. ISBN: 85-224-0273-6

VERAS, Manoel. Cloud Computing: Nova Arquitetura da TI. Brasport., 2012. ISBN:
9788574525327

WALLS, Craig; BREIDENBACH, Ryan. Spring in Action. Ed. 2, Manning


Publications,2007. ISBN: 978-1933988139

WEISS, Emily. How many pets are lost? How many find their way home? 2012.
Disponível em: https://www.aspca.org/about-us/press-releases/how-many-pets-
are-lost- how-many-find-their-way-home-aspca-survey-has-answers. Acesso em:
17 de abril de 2021.

WIKIBOOKS. Java Persistence. Wikibooks. Disponível em: https://en.wikibooks.org/


wiki/Java_Persistence. Último acesso em: 29 de outubro de 2021

ZANATTA, Alexandre Lazaretti. xScrum: Uma proposta de extensão de um


métodoágil para gerência e desenvolvimento de requisitos visando
adequação ao cmmi.2004. Disponível em: https://repositorio.ufsc.br/xmlui/
bitstream/handle/123456789/88129/214260.pdf? sequence=1&isAllowed=y
Acesso em: 17 de abril de 2021.
86

ZANETTI, Humberto Augusto. Arduino descomplicado: Como elaborar projetos de


eletrônica. editora Érica. 2015. ISBN: 978-85-365-1811-4

ZHANG, Cheng; Budgen, David. What do we know about the effectiveness of software
design patterns?. Transactions on Software Engineering. vol 38. n. 5. p. 1213-31.
setembro/outubro 2012. https://doi.org/10.1109/TSE.2011.79
87

8 RELATÓRIO COM AS LINHAS DE CÓDIGO


8.1 Apêndice A: Código-fonte do servidor
/petFinder/src/main/java/com/lino4000/petFinder/PetFinderApplication.java
package com.lino4000.petFinder;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PetFinderApplication {

public static void main(String[] args) {


SpringApplication.run(PetFinderApplication.class, args);
}
}

/petFinder/src/main/java/com/lino4000/petFinder/model/User.java
package com.lino4000.petFinder.model;

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonManagedReference;
88

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;

@Builder
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name="users")
@SuppressWarnings("serial")
public class User implements Serializable{

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@Column(unique=true)
public String username;
@NonNull
private String password;
@Column(unique=true) @NonNull
private String email;
private String info;
@OneToMany(mappedBy="user", cascade = CascadeType.REMOVE)
@JsonManagedReference
private List<Device> devices;

/petFinder/src/main/java/com/lino4000/petFinder/model/Device.java
package com.lino4000.petFinder.model;
89

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;

@Builder
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name="devices")
@SuppressWarnings("serial")
public class Device implements Serializable{

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)


private long id;
90

@Column(unique=true)
private String serial;
private String name;
@ManyToOne @NonNull
@JsonBackReference
private User user;
@OneToMany(mappedBy="device",cascade = CascadeType.REMOVE)
@JsonManagedReference
private List<Sensor> sensores;
}

/petFinder/src/main/java/com/lino4000/petFinder/model/Sensor.java
package com.lino4000.petFinder.model;

import java.io.Serializable;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
91

import lombok.NoArgsConstructor;
import lombok.NonNull;

@Builder
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name="sensors", uniqueConstraints = { @UniqueConstraint(columnNames =
{"device_id", "type"}) })
@SuppressWarnings("serial")
public class Sensor implements Serializable{

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)


private long id;
@ManyToOne @NonNull
@JsonBackReference
private Device device;
@NonNull
private SensorType type;
@OneToMany(mappedBy="sensor", cascade = CascadeType.REMOVE)
@JsonManagedReference
private List<SensorStatus> status;

public enum SensorType {


LATITUDE,
LONGITUDE,
ACCURACY,
GYROSCOPE
}
}

/petFinder/src/main/java/com/lino4000/petFinder/model/SensorStatus.java
92

package com.lino4000.petFinder.model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import com.fasterxml.jackson.annotation.JsonBackReference;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;

@Builder
@Data
@Entity
@AllArgsConstructor
@NoArgsConstructor
@SuppressWarnings("serial")
public class SensorStatus implements Serializable{

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)


private long id;
@Temporal(TemporalType.TIMESTAMP)
private Date creationDateTime;
93

@ManyToOne @NonNull
@JsonBackReference
private Sensor sensor;
@NonNull
private String value;
}

/petFinder/src/main/java/com/lino4000/petFinder/model/VerificationToken.java
package com.lino4000.petFinder.model;

import java.util.Calendar;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.ForeignKey;

@Entity
public class VerificationToken {

private static final int EXPIRATION = 60 * 24;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String token;


94

@OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)


@JoinColumn(nullable = false, name = "user_id", foreignKey = @ForeignKey(name
= "FK_VERIFY_USER"))
private User user;

private Date expiryDate;

public VerificationToken() {
super();
}

public VerificationToken(final String token) {


super();

this.token = token;
this.expiryDate = calculateExpiryDate(EXPIRATION);
}

public VerificationToken(final String token, final User user) {


super();

this.token = token;
this.user = user;
this.expiryDate = calculateExpiryDate(EXPIRATION);
}

public Long getId() {


return id;
}

public String getToken() {


return token;
}
95

public void setToken(final String token) {


this.token = token;
}

public User getUser() {


return user;
}

public void setUser(final User user) {


this.user = user;
}

public Date getExpiryDate() {


return expiryDate;
}

public void setExpiryDate(final Date expiryDate) {


this.expiryDate = expiryDate;
}

private Date calculateExpiryDate(final int expiryTimeInMinutes) {


final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(new Date().getTime());
cal.add(Calendar.MINUTE, expiryTimeInMinutes);
return new Date(cal.getTime().getTime());
}

public void updateToken(final String token) {


this.token = token;
this.expiryDate = calculateExpiryDate(EXPIRATION);
}
96

//

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getExpiryDate() == null) ? 0 :
getExpiryDate().hashCode());
result = prime * result + ((getToken() == null) ? 0 : getToken().hashCode());
result = prime * result + ((getUser() == null) ? 0 : getUser().hashCode());
return result;
}

@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final VerificationToken other = (VerificationToken) obj;
if (getExpiryDate() == null) {
if (other.getExpiryDate() != null) {
return false;
}
} else if (!getExpiryDate().equals(other.getExpiryDate())) {
return false;
}
if (getToken() == null) {
97

if (other.getToken() != null) {
return false;
}
} else if (!getToken().equals(other.getToken())) {
return false;
}
if (getUser() == null) {
if (other.getUser() != null) {
return false;
}
} else if (!getUser().equals(other.getUser())) {
return false;
}
return true;
}

@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("Token
[String=").append(token).append("]").append("[Expires").append(expiryDate).append(
"]");
return builder.toString();
}

/petFinder/src/main/java/com/lino4000/petFinder/config/SecurityConfiguration.java
package com.lino4000.petFinder.config;

import java.util.HashMap;
import java.util.Map;
98

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfig
urerAdapter;
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Bean
public PasswordEncoder passwordEncoder() {
Map<String, PasswordEncoder> encoders = new HashMap<>();

encoders.put("argon2", new Argon2PasswordEncoder());

return new DelegatingPasswordEncoder("argon2", encoders);


}

public void addResourceHandlers(ResourceHandlerRegistry registry) {


if (!registry.hasMappingForPattern("/img/**")) {
registry.addResourceHandler("/img/**").addResourceLocations(
"classpath:/static/img/");
}
if (!registry.hasMappingForPattern("/theme/**")) {
registry.addResourceHandler("/theme/**").addResourceLocations(
"classpath:/static/theme/");
99

}
if (!registry.hasMappingForPattern("/js/**")) {
registry.addResourceHandler("/js/**").addResourceLocations(
"classpath:/static/js/");
}
}

@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(
"/console/**",
"/img/**",
"/js/**",
"/theme/style.css",
"/theme/favicon.png"
);
}

protected void configure(HttpSecurity http) throws Exception {


http
.csrf()
.ignoringAntMatchers("/nocsrf","/device/**", "/logout")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and()
.formLogin()
.loginPage("/login")
100

.loginProcessingUrl("/auth").permitAll()
.defaultSuccessUrl("/dashboard/welcome")
.and()
.authorizeRequests()
.antMatchers("/register").permitAll()
.antMatchers("/view/*").permitAll()
.antMatchers(HttpMethod.GET,"/device/**").permitAll()
.antMatchers(HttpMethod.POST,"/device/**").permitAll()
.antMatchers(HttpMethod.PUT,"/device/**").permitAll()
.anyRequest().authenticated();
}
}

/petFinder/src/main/java/com/lino4000/petFinder/config/WebConfig.java
package com.lino4000.petFinder.config;

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import
org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
101

registry.addViewController("/notFound").setViewName("forward:/dashboard/welcome
");
}

@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/notFound"));
};
}

/petFinder/src/main/java/com/lino4000/petFinder/validation/EmailValidator.java
package com.lino4000.petFinder.validation;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class EmailValidator implements ConstraintValidator<ValidEmail, String> {


private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-
]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
private static final Pattern PATTERN = Pattern.compile(EMAIL_PATTERN);

@Override
102

public boolean isValid(final String username, final ConstraintValidatorContext


context) {
return (validateEmail(username));
}

private boolean validateEmail(final String email) {


Matcher matcher = PATTERN.matcher(email);
return matcher.matches();
}
}

/petFinder/src/main/java/com/lino4000/petFinder/validation/ValidEmail.java
package com.lino4000.petFinder.validation;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;


import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ TYPE, FIELD, ANNOTATION_TYPE })


@Retention(RUNTIME)
@Constraint(validatedBy = EmailValidator.class)
@Documented
public @interface ValidEmail {

String message() default "Invalid Email";


103

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};


}

/petFinder/src/main/java/com/lino4000/petFinder/error/DeviceNotFoundException.jav
a
package com.lino4000.petFinder.error;

@SuppressWarnings("serial")
public class DeviceNotFoundException extends RuntimeException {

public DeviceNotFoundException() {
super();
}

public DeviceNotFoundException(final String message, final Throwable cause) {


super(message, cause);
}

public DeviceNotFoundException(final String message) {


super(message);
}

public DeviceNotFoundException(final Throwable cause) {


super(cause);
}
}

/petFinder/src/main/java/com/lino4000/petFinder/error/EmailAlreadyExistException.ja
va
package com.lino4000.petFinder.error;
104

@SuppressWarnings("serial")
public class EmailAlreadyExistException extends RuntimeException {

public EmailAlreadyExistException() {
super();
}

public EmailAlreadyExistException(final String message, final Throwable cause) {


super(message, cause);
}

public EmailAlreadyExistException(final String message) {


super(message);
}

public EmailAlreadyExistException(final Throwable cause) {


super(cause);
}
}

/petFinder/src/main/java/com/lino4000/petFinder/error/PasswordMatchException.java
package com.lino4000.petFinder.error;

@SuppressWarnings("serial")
public class PasswordMatchException extends RuntimeException {

public PasswordMatchException() {
super();
}

public PasswordMatchException(final String message, final Throwable cause) {


super(message, cause);
105

public PasswordMatchException(final String message) {


super(message);
}

public PasswordMatchException(final Throwable cause) {


super(cause);
}
}

/petFinder/src/main/java/com/lino4000/petFinder/error/UserAlreadyExistException.jav
a
package com.lino4000.petFinder.error;

@SuppressWarnings("serial")
public class UserAlreadyExistException extends RuntimeException{

public UserAlreadyExistException() {
super();
}

public UserAlreadyExistException(final String message, final Throwable cause) {


super(message, cause);
}

public UserAlreadyExistException(final String message) {


super(message);
}

public UserAlreadyExistException(final Throwable cause) {


super(cause);
}
106

/petFinder/src/main/java/com/lino4000/petFinder/event/OnRegistrationCompleteEven
t.java
package com.lino4000.petFinder.event;

import java.util.Locale;

import org.springframework.context.ApplicationEvent;

import com.lino4000.petFinder.model.User;

@SuppressWarnings("serial")
public class OnRegistrationCompleteEvent extends ApplicationEvent {

private final String appUrl;


private final Locale locale;
private final User user;

public OnRegistrationCompleteEvent(final User user, final Locale locale, final String


appUrl) {
super(user);
this.user = user;
this.locale = locale;
this.appUrl = appUrl;
}

//

public String getAppUrl() {


return appUrl;
}
107

public Locale getLocale() {


return locale;
}

public User getUser() {


return user;
}

/petFinder/src/main/java/com/lino4000/petFinder/event/RegistrationListener.java
package com.lino4000.petFinder.event;

import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.MessageSource;
import org.springframework.core.env.Environment;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import com.lino4000.petFinder.model.User;
import com.lino4000.petFinder.service.UserService;

@Component
public class RegistrationListener implements
ApplicationListener<OnRegistrationCompleteEvent> {
@Autowired
private UserService userService;

@Autowired
108

private MessageSource messages;

@Autowired
private JavaMailSender mailSender;

@Autowired
private Environment env;

// API

@Override
public void onApplicationEvent(final OnRegistrationCompleteEvent event) {
this.confirmRegistration(event);
}

private void confirmRegistration(final OnRegistrationCompleteEvent event) {


final User user = event.getUser();
final String token = UUID.randomUUID().toString();
userService.createVerificationTokenForUser(user, token);

final SimpleMailMessage email = constructEmailMessage(event, user, token);


mailSender.send(email);
}

//

private SimpleMailMessage constructEmailMessage(final


OnRegistrationCompleteEvent event, final User user, final String token) {
final String recipientAddress = user.getEmail();
final String subject = "Registration Confirmation";
final String confirmationUrl = event.getAppUrl() +
"/registrationConfirm.html?token=" + token;
109

final String message = messages.getMessage("message.regSuccLink", null,


"You registered successfully. To confirm your registration, please click on the below
link.", event.getLocale());
final SimpleMailMessage email = new SimpleMailMessage();
email.setTo(recipientAddress);
email.setSubject(subject);
email.setText(message + " \r\n" + confirmationUrl);
email.setFrom(env.getProperty("support.email"));
return email;
}

/petFinder/src/main/java/com/lino4000/petFinder/repository/UserRepository.java
package com.lino4000.petFinder.repository;

import java.util.Optional;

import org.springframework.data.repository.CrudRepository;

import com.lino4000.petFinder.model.User;

public interface UserRepository extends CrudRepository<User, Long>{

public boolean existsByEmail(String email);


public boolean existsByUsername(String username);
public Optional<User> findByEmail(String email);
public Optional<User> findByUsername(String username);
}

/petFinder/src/main/java/com/lino4000/petFinder/repository/VerificationTokenReposit
ory.java
110

package com.lino4000.petFinder.repository;

import java.util.Date;
import java.util.stream.Stream;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import com.lino4000.petFinder.model.User;
import com.lino4000.petFinder.model.VerificationToken;

public interface VerificationTokenRepository extends


JpaRepository<VerificationToken, Long> {

VerificationToken findByToken(String token);

VerificationToken findByUser(User user);

Stream<VerificationToken> findAllByExpiryDateLessThan(Date now);

void deleteByExpiryDateLessThan(Date now);

@Modifying
@Query("delete from VerificationToken t where t.expiryDate <= ?1")
void deleteAllExpiredSince(Date now);
}

/petFinder/src/main/java/com/lino4000/petFinder/repository/DeviceRepository.java
package com.lino4000.petFinder.repository;

import org.springframework.data.repository.CrudRepository;
111

import com.lino4000.petFinder.model.Device;

public interface DeviceRepository extends CrudRepository<Device, Long>{

public Device findBySerial(String serial);


public void deleteBySerial(String serial);

/petFinder/src/main/java/com/lino4000/petFinder/repository/SensorRepository.java
package com.lino4000.petFinder.repository;

import java.util.List;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

import com.lino4000.petFinder.model.Device;
import com.lino4000.petFinder.model.Sensor;
import com.lino4000.petFinder.model.Sensor.SensorType;

public interface SensorRepository extends CrudRepository<Sensor, Long>{

public List<Sensor> findAllByDevice(Device device);


public Sensor findById(int id);
@Query(value = "SELECT s FROM Sensor s WHERE s.device = :device and
s.type = :type")
public Sensor findByDeviceAndType(@Param("device") Device device,
@Param("type") SensorType type);

}
112

/petFinder/src/main/java/com/lino4000/petFinder/repository/SensorStatusRepository.j
ava
package com.lino4000.petFinder.repository;

import java.util.List;

import org.springframework.data.repository.CrudRepository;

import com.lino4000.petFinder.model.Sensor;
import com.lino4000.petFinder.model.SensorStatus;

public interface SensorStatusRepository extends CrudRepository<SensorStatus,


Long>{

public List<SensorStatus> findAllSensorStatusBySensor(Sensor sensor);


public SensorStatus findById(long id);
}

/petFinder/src/main/java/com/lino4000/petFinder/service/UserService.java
package com.lino4000.petFinder.service;

import java.security.Principal;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
113

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.lino4000.petFinder.dto.RegisterRequest;
import com.lino4000.petFinder.error.EmailAlreadyExistException;
import com.lino4000.petFinder.error.UserAlreadyExistException;
import com.lino4000.petFinder.model.Device;
import com.lino4000.petFinder.model.User;
import com.lino4000.petFinder.model.VerificationToken;
import com.lino4000.petFinder.repository.DeviceRepository;
import com.lino4000.petFinder.repository.UserRepository;
import com.lino4000.petFinder.repository.VerificationTokenRepository;

@Service
@Transactional
public class UserService implements UserDetailsService{

@Autowired
private UserRepository userRepository;

@Autowired
private DeviceRepository deviceRepository;

@Autowired
private PasswordEncoder passwordEncoder;

@Autowired
private MessageSource messages;

@Autowired
private VerificationTokenRepository tokenRepository;

@Override
114

public UserDetails loadUserByUsername(String username) throws


UsernameNotFoundException {
Optional<User> user = userRepository.findByUsername(username);
user.orElseThrow(() -> new
UsernameNotFoundException(messages.getMessage("user.username.notFound",
null, null)));

return new
org.springframework.security.core.userdetails.User(user.get().getUsername(),
user.get().getPassword(), true, true, true, true, new HashSet<>());
}

public boolean registerNewUser(RegisterRequest registerRequest) throws


UserAlreadyExistException {

if ( usernameExists( registerRequest.getUsername() ) ) {
throw new
UserAlreadyExistException(messages.getMessage("user.username.alreadExists",nul
l,null));
}

if ( emailExists( registerRequest.getEmail() ) ) {
throw new
EmailAlreadyExistException(messages.getMessage("user.email.alreadExists",null,nu
ll));
}

userRepository.save(
User.builder()
.username(registerRequest.getUsername())
.password(passwordEncoder.encode(registerRequest.getPassword()))
.email(registerRequest.getEmail())
.build()
115

);

return true;
}

public List<Device> getDeviceList(String username){


return userRepository.findByUsername(username).get().getDevices();
}

public boolean deleteDevice(String serial) {

deviceRepository.deleteBySerial(serial);
return true;
}

public User getUser(Principal principal) {


Optional<User> user =
userRepository.findByUsername(principal.getName());
user.orElseThrow(() -> new
UsernameNotFoundException(messages.getMessage("user.username.notFound",
null, null)));
return user.get();
}

public void createVerificationTokenForUser(final User user, final String token) {


final VerificationToken myToken = new VerificationToken(token, user);
tokenRepository.save(myToken);
}

private boolean emailExists(String email) {


return userRepository.existsByEmail(email);
}
116

private boolean usernameExists(String username) {


return userRepository.existsByUsername(username);
}

/petFinder/src/main/java/com/lino4000/petFinder/service/DeviceService.java
package com.lino4000.petFinder.service;

import java.util.ArrayList;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lino4000.petFinder.dto.DeviceReceiveLocation;
import com.lino4000.petFinder.dto.PathToGoogleMaps;
import com.lino4000.petFinder.model.Device;
import com.lino4000.petFinder.model.Sensor.SensorType;
import com.lino4000.petFinder.model.SensorStatus;
import com.lino4000.petFinder.repository.DeviceRepository;
import com.lino4000.petFinder.repository.SensorRepository;
import com.lino4000.petFinder.repository.SensorStatusRepository;

@Service
@Transactional
public class DeviceService {

@Autowired
private DeviceRepository deviceRepository;
117

@Autowired
private SensorRepository sensorRepository;

@Autowired
private SensorStatusRepository sensorStatusRepository;

public DeviceReceiveLocation newLocation(String serial,


DeviceReceiveLocation location) {
Device device = deviceRepository.findBySerial(serial);
SensorStatus statusLat = SensorStatus.builder()
.value(Double.toString(location.latitude))
.sensor(sensorRepository.findByDeviceAndType(device,
SensorType.LATITUDE))
.build();

SensorStatus statusLon = SensorStatus.builder()


.value(Double.toString(location.longitude))
.sensor(sensorRepository.findByDeviceAndType(device,
SensorType.LONGITUDE))
.build();

SensorStatus statusAcc = SensorStatus.builder()


.value(Double.toString(location.accuracy))
.sensor(sensorRepository.findByDeviceAndType(device,
SensorType.ACCURACY))
.build();

sensorStatusRepository.save(statusLat);
sensorStatusRepository.save(statusLon);
sensorStatusRepository.save(statusAcc);
return location;
}
118

public List<PathToGoogleMaps> getPath(String serial) {


List<SensorStatus> sensorsLat =
sensorStatusRepository.findAllSensorStatusBySensor(
sensorRepository.findByDeviceAndType(
deviceRepository.findBySerial(serial),
SensorType.LATITUDE
)
);
List<SensorStatus> sensorsLon =
sensorStatusRepository.findAllSensorStatusBySensor(
sensorRepository.findByDeviceAndType(
deviceRepository.findBySerial(serial),
SensorType.LONGITUDE
)
);

List<PathToGoogleMaps> locations = new ArrayList<>();

for(int i=0; i < sensorsLat.size(); i++) {


locations.add(
PathToGoogleMaps.builder()
.lat(
Double.parseDouble(sensorsLat.get(i).getValue() ) )
.lng(
Double.parseDouble(sensorsLon.get(i).getValue() ) )
.build()
);
}

return locations;

}
119

/petFinder/src/main/java/com/lino4000/petFinder/dto/RegisterRequest.java
package com.lino4000.petFinder.dto;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

import com.lino4000.petFinder.validation.ValidEmail;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Value;

@Builder
@Value
@AllArgsConstructor
public class RegisterRequest {

String username;

@ValidEmail
@NotNull
@NotEmpty
String email;
String password;
String passwordConfirmation;
String info;
String device;
}

/petFinder/src/main/java/com/lino4000/petFinder/dto/DeviceReceiveLocation.java
120

package com.lino4000.petFinder.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Value;

@Builder
@Value
@AllArgsConstructor
public class DeviceReceiveLocation {

public double latitude;


public double longitude;
public double accuracy;
}

/petFinder/src/main/java/com/lino4000/petFinder/dto/DeviceResponse.java
package com.lino4000.petFinder.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DeviceResponse {
private String serial;
private String name;
}
121

/petFinder/src/main/java/com/lino4000/petFinder/dto/GenericResponse.java
package com.lino4000.petFinder.dto;

import lombok.Builder;
import lombok.Value;

@Builder
@Value
public class GenericResponse {

public String title;


public String message;
public String action;
}

/petFinder/src/main/java/com/lino4000/petFinder/dto/PathToGoogleMaps.java
package com.lino4000.petFinder.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Value;

@Builder
@Value
@AllArgsConstructor
public class PathToGoogleMaps {

public double lat;


public double lng;
}

/petFinder/src/main/java/com/lino4000/petFinder/controller/PublicController.java
package com.lino4000.petFinder.controller;
122

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lino4000.petFinder.dto.GenericResponse;
import com.lino4000.petFinder.dto.RegisterRequest;
import com.lino4000.petFinder.error.EmailAlreadyExistException;
import com.lino4000.petFinder.error.UserAlreadyExistException;
import com.lino4000.petFinder.service.UserService;

@Controller
public class PublicController {

@Autowired
public UserService userService;

@Autowired
private MessageSource messages;

@GetMapping("/login")
public String loginPage(ModelMap map, final HttpServletRequest request) {
123

map.addAttribute("errMessage",
messages.getMessage("user.tryToLogin.failure", null, request.getLocale() ) );
return "login";
}

@GetMapping("/register")
public String registerPage(@ModelAttribute("user") RegisterRequest
registerRequest) {
return "register";
}

@PostMapping("/register")
@ResponseBody
public GenericResponse registering(@RequestBody @Valid final RegisterRequest
registerRequest, final HttpServletRequest request, final Errors errors) {

try {

userService.registerNewUser(registerRequest);

} catch (final UserAlreadyExistException ex) {

return GenericResponse.builder()
.title( messages.getMessage("user.registration.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();

} catch (final EmailAlreadyExistException ex) {

return GenericResponse.builder()
.title( messages.getMessage("user.registration.failure", null,
request.getLocale()) )
124

.message( ex.getMessage() )
.build();

} catch (final IllegalArgumentException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("user.registration.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("user.registration.success.title", null,
request.getLocale()) )
.message(
messages.getMessage("user.registration.success.message", null,
request.getLocale()) )
.build();
}

@GetMapping("/view/{serial}")
public String viewDevice(@PathVariable("serial") String serial, ModelMap map)
{
if(null == serial)
return "redirect:/login";
125

if(null == userService.getDevice(serial))
return "redirect:/dashboard/device/add?serial="+serial;
map.addAttribute("info",
userService.getDevice(serial).getUser().getInfo());
return "device";
}

/petFinder/src/main/java/com/lino4000/petFinder/controller/PrivateController.java
package com.lino4000.petFinder.controller;

import java.security.Principal;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lino4000.petFinder.dto.DeviceResponse;
import com.lino4000.petFinder.dto.GenericResponse;
import com.lino4000.petFinder.dto.RegisterRequest;
import com.lino4000.petFinder.model.Device;
126

import com.lino4000.petFinder.model.User;
import com.lino4000.petFinder.service.DeviceService;
import com.lino4000.petFinder.service.UserService;

@Controller
@RequestMapping("/dashboard")
public class PrivateController {

@Autowired
private UserService userService;

@Autowired
private DeviceService deviceService;

@Autowired
private MessageSource messages;

@GetMapping("/welcome")
public String index(ModelMap map, Principal principal) {
map.addAttribute("devices",
userService.getDeviceList(principal.getName()));
map.addAttribute("device",
Device.builder().user(userService.getUser(principal)).build());
return "welcome";
}

@GetMapping("/account")
public String account(ModelMap map, Principal principal, RegisterRequest
user) {
User u = userService.getUser(principal);
map.addAttribute("user", RegisterRequest.builder()
.username(u.getUsername())
.email(u.getEmail())
127

.info(u.getInfo())
.password("")
.passwordConfirmation("")
.device("")
.build()
);
return "account";
}

@GetMapping("/view")
public String viewDevice(Principal principal, ModelMap map) {
map.addAttribute("info", userService.getUser(principal).getInfo());
return "device";
}

@GetMapping("/device/add")
public String deviceAdd(@RequestParam(required = false) String serial,
ModelMap map, DeviceResponse device) {
map.addAttribute("serial", serial);
map.addAttribute("device", DeviceResponse.builder().build());
return "device-add";
}

@PostMapping("/device/add")
@ResponseBody
public GenericResponse deviceAdding(@RequestBody DeviceResponse
device, Principal principal, final HttpServletRequest request) {
try {
deviceService.addDevice(device, principal.getName());
} catch (final IllegalArgumentException ex) {

return GenericResponse.builder()
128

.title( messages.getMessage("generic.title.failure", null,


request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.device.add.success", null,
request.getLocale()))
.build();
}

@GetMapping("/device/{serial}/finder")
public String getMapPage(@PathVariable("serial") String serial, ModelMap
map) {
map.addAttribute("path", deviceService.getPath(serial));
return "finder";
}

@PostMapping("/device/{serial}/change-name")
@ResponseBody
public GenericResponse changeDeviceName(@PathVariable("serial") String
serial, @RequestBody DeviceResponse device,final HttpServletRequest request) {
129

try {
userService.changeDeviceName(serial, device.getName());
} catch (final IllegalArgumentException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.device.changeName.success",
null, request.getLocale()))
.build();
}

@PostMapping("/device/{serial}/delete")
@ResponseBody
public GenericResponse deleteDevice(@PathVariable("serial") String serial,
final HttpServletRequest request) {

try {
130

deviceService.deleteDevice(serial);
} catch (final IllegalArgumentException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.device.delete.success", null,
request.getLocale()))
.build();
}

@PostMapping("/user/change-username")
@ResponseBody
public GenericResponse changeUsername( @RequestBody RegisterRequest
user, Principal principal, final HttpServletRequest request) {
try {
userService.changeUsername(principal.getName(), user.getUsername());
} catch (final IllegalArgumentException ex) {
131

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.changeUsername.success",
null, request.getLocale()))
.build();

@PostMapping("/user/change-email")
@ResponseBody
public GenericResponse changeEmail(@RequestBody RegisterRequest user,
Principal principal, final HttpServletRequest request) {
try {
userService.changeEmail(principal.getName(), user.getEmail());
} catch (final IllegalArgumentException ex) {
132

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.changeUsername.success",
null, request.getLocale()))
.build();

}
@PostMapping("/user/change-info")
@ResponseBody
public GenericResponse changeInfo(@RequestBody User user, Principal
principal, final HttpServletRequest request) {
try {
userService.changeInfo(principal.getName(), user.getInfo());
} catch (final RuntimeException ex) {

return GenericResponse.builder()
133

.title( messages.getMessage("generic.title.failure", null,


request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.changeInfo.success", null,
request.getLocale()))
.build();

@PostMapping("/user/change-password")
@ResponseBody
public GenericResponse changePassword(@RequestBody RegisterRequest
user, Principal principal, final HttpServletRequest request) {
try {
userService.changePassword(principal.getName(),
user.getPassword(),user.getPasswordConfirmation());
} catch (final IllegalArgumentException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( ex.getMessage() )
.build();
} catch (final RuntimeException ex) {

return GenericResponse.builder()
134

.title( messages.getMessage("generic.title.failure", null,


request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.changeInfo.success", null,
request.getLocale()))
.build();

@PostMapping("/user/delete")
@ResponseBody
public GenericResponse deleteDevice(@RequestBody RegisterRequest user,
Principal principal, final HttpServletRequest request) {

try {
userService.deleteUser(principal.getName());
} catch (final RuntimeException ex) {

return GenericResponse.builder()
.title( messages.getMessage("generic.title.failure", null,
request.getLocale()) )
.message( messages.getMessage("generic.message.failure",
null, request.getLocale()) )
.build();
}
135

return GenericResponse.builder()
.title( messages.getMessage("generic.title.success", null,
request.getLocale()) )
.message( messages.getMessage("user.delete.success", null,
request.getLocale()) )
.build();
}

/petFinder/src/main/java/com/lino4000/petFinder/controller/DeviceController.java
package com.lino4000.petFinder.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lino4000.petFinder.dto.DeviceReceiveLocation;
import com.lino4000.petFinder.dto.PathToGoogleMaps;
import com.lino4000.petFinder.service.DeviceService;
136

@Controller
@RequestMapping("/device")
public class DeviceController {

@Autowired
DeviceService deviceService;

@PutMapping("{serial}/newlocation")
@ResponseBody
public DeviceReceiveLocation newLocation(@PathVariable("serial") String serial,
@RequestBody @Valid final DeviceReceiveLocation locationReceived,
@Param("nonce") long nonce) {

return deviceService.newLocation(serial, locationReceived);


}

@GetMapping("{serial}/path")
@ResponseBody
public List<PathToGoogleMaps> getPath(@PathVariable("serial") String serial,
@Param("nonce") long nonce) {
return deviceService.getPath(serial);
}

/petFinder/src/main/resources/templates/login.html
<!doctype html>
<html lang="pt-br">
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PetFinder</title>
<link rel="stylesheet" href="/theme/style.css">
137

<link rel="shortcut icon" href="/theme/favicon.png" />


<script type="text/javascript" src="/js/functions.js"></script>
</head>
<body class="login">
<div class="wrapper h-100 container-fluid">
<div class="row h-100 justify-content-center align-items-center">
<div class="login-form col">
<div class="logo">
<img src="/img/logo.png" />
</div>
<form th:action="@{/auth}" method="post">
<div class="mb-3">
<label for="login" class="form-
label">Email ou usuário</label>
<span class="input-group-text bi bi-
person-fill">
</span>
<input type="text" name="username"
class="form-control" id="login" aria-describedby="emailHelp">
</div>
<div class="mb-3">
<label for="password" class="form-
label">Senha</label>
<span class="input-group-text bi bi-
key-fill">
</span>
<input type="password" class="form-
control" id="password" name="password">
</div>
<div class="mb-3 hstack">
<a href="#" class="">Esqueci a
senha</a>
138

<a href="/register" class="ms-


auto">Criar conta</a>
</div>
<button type="submit" class="btn btn-
secondary w-100 text-light">Entrar</button>
</form>

</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-
/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
crossorigin="anonymous"></script>
</body>
</html>

/petFinder/src/main/resources/templates/register.html
<!doctype html>
<html lang="pt-br">
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PetFinder</title>
<link rel="stylesheet" href="/theme/style.css">
<link rel="shortcut icon" href="/theme/favicon.png" />
<script type="text/javascript" src="/js/functions.js"></script>
</head>
<body class="dark register">
<div id="responser" class="modal fade" tabindex="-1" role="dialog" aria-
hidden="true">
<div class="modal-dialog modal-dialog-centered">
139

<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p></p>
</div>
</div>
</div>
</div>
<div class="wrapper h-100 container-fluid">
<div class="row h-100 justify-content-center align-items-center">
<div class="login-form col">
<div class="logo">
<img src="/img/logo.png" />
</div>
<form class="json" th:action="@{/register}"
th:object="${user}" method="post">
<div class="mb-3">
<label for="user" class="form-
label">Usuário</label>
<span class="input-group-text bi bi-
person-fill">
</span>
<input type="text" class="form-
control" id="user" aria-describedby="userlHelp" th:field="*{username}" >
</div>
<div class="mb-3">
<label for="email" class="form-
label">Email</label>
140

<span class="input-group-text bi bi-


envelope-fill">
</span>
<input type="email" class="form-
control" id="email" aria-describedby="emailHelp" th:field="*{email}">
</div>
<div class="mb-3">
<label for="password1" class="form-
label">Senha</label>
<span class="input-group-text bi bi-
key-fill">
</span>
<input type="password" class="form-
control" id="password1" aria-describedby="password1Help" th:field="*{password}">
</div>
<div class="mb-3">
<label for="password2" class="form-
label">Confirmar senha</label>
<span class="input-group-text bi bi-
key-fill">
</span>
<input type="password" class="form-
control" id="password2" aria-describedby="password2Help"
th:field="*{passwordConfirmation}">
</div>
<input type="submit" class="btn btn-
secondary w-100 text-light" value="Criar" />
<div class="mb-3">
<a href="/login">Voltar</a>
</div>
</form>
</div>
</div>
141

</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-
/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
crossorigin="anonymous"></script>
</body>
</html>

/petFinder/src/main/resources/templates/welcome.html
<!doctype html>
<html lang="pt-br">
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PetFinder</title>
<link rel="stylesheet" href="/theme/style.css">
<link rel="shortcut icon" href="/theme/favicon.png" />
<script type="text/javascript" src="/js/functions.js"></script>
</head>
<body class="light dashboard welcome">
<div class="wrapper h-100 container-flex">
<header class="row justify-content-center g-0">
<div class="logo py-5 text-center col">
<img src="/img/logo.png" />
</div>
</header>
<main class="container">
<div class="row gy-4">
<div class="col col-12">
<div id="alert" class="panel p-3 bg-light
rounded">
<div class="panel-header">
142

<h2>Bem vindo!</h2>
<button type="button"
class="btn-close" aria-label="Close" data-target="#alert" data-bs-
dismiss="alert"></button>
</div>
<div class="panel-body">
<p>Parabéns pela excelente
aquisição!</p>
</div>
</div>
</div>
<div class="col col-12 col-sm-6">
<a href="#" class="btn btn-block btn-primary
w-100 bg-light bi bi-person-circle" title="Configurações de conta">
</a>
</div>
<div class="col col-12 col-sm-6">
<a href="#" type="button" class="btn btn-
block btn-primary w-100 bg-light bi bi-plus-square-dotted" title="Adicionar novo
dispositivo">
</a>
</div>
<div class="col col-12">
<div class="devices">
<h2>Dispositivos</h2>
<div class="list-group">
<!--/*/<th:block
th:each="device : ${devices}"> /*/-->
<div class="list-group-item list-
group-item-action function btn btn-primary hstack gap-2" title="Dispositivo
&quot;Cachorro&quot;">

<h4>[(${device.name})]</h4>
143

<a
th:href="@{device/}+${device.serial}+@{/finder}" class="icon rounded ms-auto">
<svg
xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor"
class="bi bi-geo-alt-fill" viewBox="0 0 16 16">
<path
d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 1 0-6 3 3 0 0 1
0 6z"/>
</svg>
</a>

<a
th:href="@{device/}+${device.serial}+@{/change-name}" class="icon rounded">
<svg
xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor"
class="bi bi-pencil-square" viewBox="0 0 16 16">
<path
d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707
0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0
0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
<path fill-
rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0
0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-
1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
</svg>
</a>

<a
th:href="@{device/}+${device.serial}+@{/delete}" class="icon rounded">
<svg
xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor"
class="bi bi-trash-fill" viewBox="0 0 16 16">
144

<path
d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1
1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1
.5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5
0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"/>
</svg>
</a>
</div>
<!--/*/</th:block> /*/-->
</div>
</div>
</div>
</div>
</main>
<footer>
</footer>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-
/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
crossorigin="anonymous"></script>
</body>
</html>

/petFinder/src/main/resources/templates/finder.html
<!doctype html>
<html lang="pt-br">
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PetFinder</title>
<link rel="stylesheet" href="/theme/style.css">
145

<link rel="shortcut icon" href="/theme/favicon.png" />


<script
src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script type="text/javascript" src="/js/functions.js"></script>
<script type="text/javascript" th:inline="javascript">
// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
function initMap() {
/*<![CDATA[*/
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 17,
center: { lat:/*[[${path[0].lat}]]*/, lng: /*[[${path[0].lng}]]*/ },
mapTypeId: "terrain",
});
const flightPlanCoordinates = /*[[${path}]]*/ [];
const flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 3,
});

flightPath.setMap(map);

var message = /*[[${path}]]*/ ;

/*]]>*/
}
</script>
</head>
146

<body class="light finder">


<div class="wrapper h-100">
<header class="container mh-20 pt-3 pb-4">
<div class="row justify-content-center g-0 h-100">
<div class="logo mh-100 text-center col">
<a class="h-100"
href="/dashboard/welcome">
<img class="mh-100"
src="/img/logo.png" />
</a>
</div>
</div>
</header>
<div id="map" class="h-100 rounded-top rounded-3"></div>

<!-- Async script executes immediately and must be after any


DOM elements used in callback. -->
<script

src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPx
aFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly&channel=2"
async
></script>
<footer>
</footer>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-
/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
crossorigin="anonymous"></script>
</body>
</html>
147

/petFinder/src/main/resources/static/theme/scss/style.scss
@import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-
icons.css");
@import "../bootstrap/functions";
$primary:#4365C9;
$secondary:#728CD7;
@import "../bootstrap/bootstrap";

@import "../bootstrap/variables";
@import "../bootstrap/utilities";

$custom-height: (
"10": 10%,
"20": 20%,
"30": 30%,
"40": 40%,
"50": 50%,
"60": 60%,
"70": 70%,
"80": 80%,
"90": 90%,
);

$utilities: map-merge(
$utilities,
(
"height": map-merge(
map-get($utilities, "height"),
(
values: map-merge(
map-get(map-get($utilities, "height"), "values"),
$custom-height,
148

),
),
),
)
);
$utilities: map-merge(
$utilities,
(
"max-height": map-merge(
map-get($utilities, "max-height"),
(
values: map-merge(
map-get(map-get($utilities, "max-height"), "values"),
$custom-height,
),
),
),
)
);
@import "../bootstrap/bootstrap";

html, body{height:100%}
body {background-color:#4365C9;color:#FFF;}
main{padding-bottom:20px;}

.login .wrapper, .register .wrapper{max-width: 310px;min-width: 240px;}


.dashboard main.container{max-width:680px;}

.panel{color:#607ED2;}
.panel-header{
display:flex;
justify-content: space-between;
}
149

.panel-body p:last-child{margin-bottom:0}

body{
& .modal p, & .modal h5{color:#607ED2;}
& .modal p{margin-bottom:0}

& .form-control{box-shadow: inset 0 0 10px


rgba(#000000,.4);color:#607ED2;padding-left: 42px;}
& .form-control:focus{box-shadow: inset 0 0 10px rgba(#000000,.3), 0 0 0
0.25rem rgba(#FFFFFF,.25);color:#607ED2}

& .login-form a{color:#FFF;text-decoration:none}


& .login-form a:hover{text-decoration:underline}
}

.login-form .logo{text-align:center;padding-bottom:30px;}
body.finder header.container{
height:180px;box-sizing:border-box;
& img{}
}
#map{min-height:80%}
.input-group-text{
background:none;
border:none;
color:#607ED2;
font-size:26px;
padding: .375rem 0.55rem;
position: absolute;

&::before{font-size:26px;}
&.bi-envelope-fill{padding: .600rem 0.70rem;}
}
150

.mb-3 + .btn{margin-top:1rem;}
.mb-3 + .btn:last-child{margin-top:0;}
.btn + .mb-3{margin-top:1rem;}

.btn-primary.btn-block, .devices .list-group-item{


border:none;color:#728CD7;
&::before{font-size:64px;line-height: 128px;vertical-align:middle}
&:active {border:none;color:#728CD7 !important;}
&:hover {border:none;color:#4365C9 !important;box-shadow:0 0 0 0.25rem
rgba(#FFFFFF,.25);}
}

.devices{
& h2{color:#FFF}
& .list-group-item{padding: 0.5rem 0.5rem;}
& .list-group-item + .list-group-item{margin-top:10px;}
& .list-group-item h4{margin-bottom:0}
& .list-group-item .icon{border:1px solid #728CD7;padding:5px;}
}

/petFinder/src/main/resources/static/js/functions.js
var modal;
window.onload = function(){
prepareForms();
var responser = document.getElementById('responser');
}

function sendForm( event ) {


let formData = new FormData(event.target);
let url = event.target.action + '?';
url += '_csrf='+ formData.get('_csrf');
formData.delete('_csrf');
151

let fields = {};


formData.forEach((value, key) => fields[key] = value)

postJson(url, JSON.stringify(fields) ).then( response => {


responseDelegator(response);

})
event.preventDefault();
};

async function postJson (url, req) {


let response = await fetch(url,{
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: req
});
let json = await response.json();
return json;
}

function responseDelegator(response){

if (modal === undefined)


modal = new bootstrap.Modal(responser);
//Se existir e tiver algo, faça
if(response.title && response.title !== undefined)
responser.getElementsByClassName('modal-title')[0].innerHTML =
response.title;
if(response.message && response.message !== undefined)
152

responser.querySelector('.modal-body p').innerHTML =
response.message;
if(response.action && response.action !== undefined)
responser.querySelector('.modal-body p').innerHTML = response.action;
modal.show();
}

function prepareForms(){
document.querySelectorAll('form.json').forEach(
(e)=> e.addEventListener( 'submit', sendForm )
)
}
153

8.2 Apêndice B: Código fonte do NodeMCU


#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include "ESP8266WiFi.h"
#include "WiFiClientSecure.h"
#include <WiFiClient.h>

char ssid[] = "SSID"; // seu nome SSID de rede


char pass[] = "SENHA"; // sua senha de rede

//Credenciais para Google GeoLocation API ...

const char* Host = "www.googleapis.com";


String thisPage = "/geolocation/v1/geolocate?key=";
String key = "AIzaSyCHh4ve_OY1jhxxLy6CODsMMl-lXmrM5LA";

int status = WL_IDLE_STATUS;


String jsonString = "{\n";
String jsonLocation = "{\n";

double latitude = 0.0;


double longitude = 0.0;
double accuracy = 0.0;
int more_text = 1; // definido como 1 para mais saída de depuração

void setup() {
Serial.begin(9600);
Serial.println("Start");

// Define o WiFi para o modo de estação e desconecte-se de um AP se ele tiver sido


conectado anteriormente
WiFi.mode(WIFI_STA);
WiFi.disconnect();
154

delay(200);
Serial.println("Setup done");

// We start by connecting to a WiFi network


Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);

while (WiFi.status() != WL_CONNECTED) {


delay(500);
Serial.print(".");
}
Serial.println(".");

void loop() {

char bssid[6];
DynamicJsonBuffer jsonBuffer;
Serial.println("scan start");

// Retorno do número de redes encontradas


int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0)
Serial.println("no networks found");
else
{
Serial.print(n);
Serial.println(" networks found...");

if (more_text) {
155

Serial.println("\"wifiAccessPoints\": [");
for (int i = 0; i < n; ++i)
{
Serial.println("{");
Serial.print("\"macAddress\" : \"");
Serial.print(WiFi.BSSIDstr(i));
Serial.println("\",");
Serial.print("\"signalStrength\": ");
Serial.println(WiFi.RSSI(i));
if (i < n - 1)
{
Serial.println("},");
}
else
{
Serial.println("}");
}
}
Serial.println("]");
Serial.println("}");
}
Serial.println(" ");
}

// Construção do JSON
jsonString = "{\n";
jsonString += "\"considerIp\": false,\n";
jsonString += "\"wifiAccessPoints\": [\n";
for (int j = 0; j < n; ++j)
{
jsonString += "{\n";
jsonString += "\"macAddress\" : \"";
jsonString += (WiFi.BSSIDstr(j));
156

jsonString += "\",\n";
jsonString += "\"signalStrength\": ";
jsonString += WiFi.RSSI(j);
jsonString += "\n";
if (j < n - 1)
{
jsonString += "},\n";
}
else
{
jsonString += "}\n";
}
}
jsonString += ("]\n");
jsonString += ("}\n");

//Conecte-se ao cliente e faz a chamada API


delay(5000);
WiFiClientSecure client;
client.setInsecure ();
Serial.print("Requesting URL: ");
Serial.println("https://" + (String)Host + thisPage + key);
Serial.println(" ");
if (!client.connect("www.googleapis.com", 443)) {
Serial.println("Nao consegui conexao a API");
}else {
Serial.println("Connected");
client.println("POST " + thisPage + key + " HTTP/1.1");
client.println("Host: " + (String)Host);
client.println("Connection: close");
client.println("Content-Type: application/json");
client.println("User-Agent: Arduino/1.0");
157

client.print("Content-Length: ");
client.println(jsonString.length());
client.println();
client.print(jsonString);
delay(1000);
}

//Leitura e análise todas as linhas da resposta do servidor


while (client.available()) {
String line = client.readStringUntil('\r');
if (more_text) {
Serial.print(line);
}
JsonObject& root = jsonBuffer.parseObject(line);
if (root.success()) {
latitude = root["location"]["lat"];
longitude = root["location"]["lng"];
accuracy = root["accuracy"];

WiFiClient wifiClient;
HTTPClient http;
if (http.begin(wifiClient,"http://ec2-18-222-181-104.us-east-
2.compute.amazonaws.com:8080/device/1234/newlocation?nonce=2389749874798"
)){
Serial.println("http.begin OK");
}
delay(500);

http.addHeader("Content-Type", "application/json");
http.addHeader("Accept", "application/json");

jsonLocation = "{\"latitude\" : \"";


158

jsonLocation += latitude;
jsonLocation += "\",";
jsonLocation += "\"longitude\":\"";
jsonLocation += longitude;
jsonLocation += "\",";
jsonLocation += "\"accuracy\":\"";
jsonLocation += accuracy;
jsonLocation += "\"";
jsonLocation += ("}");

// Envio

int httpResponseCode = http.PUT(jsonLocation);


Serial.println(httpResponseCode);
if (httpResponseCode > 0) {
const String& payload = http.getString();
Serial.println(httpResponseCode);
Serial.println("PAYLOAD AQUI: " + payload);
switch (httpResponseCode){
yield();

case 200:
Serial.println("Requisicao concluída com sucesso");
break;

case 201:
Serial.println("Requisicao id2 POST!");
break;

case 404:
Serial.println("Site não encontrado!");
break;
159

default:
break;
}
}
else {
Serial.println ("FAIL REQUEST");
}
http.end();
}
}

Serial.println("closing connection");
Serial.println();
client.stop();
Serial.println(jsonLocation);
delay(120000);

Você também pode gostar