Mudanças entre as edições de "PJI29006-2015-1-Wiki do Projeto"
(61 revisões intermediárias por 6 usuários não estão sendo mostradas) | |||
Linha 1: | Linha 1: | ||
+ | __NOTOC__ | ||
=Sistema de Automatização de Sala de Aula= | =Sistema de Automatização de Sala de Aula= | ||
Linha 4: | Linha 5: | ||
* [https://dotproject.sj.ifsc.edu.br/?m=projects&a=view&project_id=14 Sistema de Gerenciamento de Projetos (dotProject)] | * [https://dotproject.sj.ifsc.edu.br/?m=projects&a=view&project_id=14 Sistema de Gerenciamento de Projetos (dotProject)] | ||
− | * [ | + | * [https://github.com/guialbu/Sistema-Webba Repositório do Código Fonte (GIT)] |
− | |||
− | |||
==Descrição== | ==Descrição== | ||
Linha 113: | Linha 112: | ||
{{collapse bottom}} | {{collapse bottom}} | ||
+ | ===Casos de Uso=== | ||
− | + | {{collapse top| Descrição dos Casos de Uso}} | |
<center>[[Arquivo:caso_de_uso.png| 650px]]</center> | <center>[[Arquivo:caso_de_uso.png| 650px]]</center> | ||
− | |||
− | |||
====CSU01==== | ====CSU01==== | ||
Linha 239: | Linha 237: | ||
'''Pós-condições:''' Projetor ligado e funcionando de acordo como o usuário solicitou | '''Pós-condições:''' Projetor ligado e funcionando de acordo como o usuário solicitou | ||
− | |||
<center>[[Arquivo:ana4.png| 650px]]</center> | <center>[[Arquivo:ana4.png| 650px]]</center> | ||
− | |||
====CSU05==== | ====CSU05==== | ||
Linha 315: | Linha 311: | ||
====CSU07==== | ====CSU07==== | ||
− | |||
'''Desligando a iluminação''' | '''Desligando a iluminação''' | ||
Linha 372: | Linha 367: | ||
b. O usuário ajusta a posição da cortina conforme sua escolha de forma manual | b. O usuário ajusta a posição da cortina conforme sua escolha de forma manual | ||
− | |||
− | |||
<center>[[Arquivo:pj17.png| 650px]]</center> | <center>[[Arquivo:pj17.png| 650px]]</center> | ||
Linha 428: | Linha 421: | ||
3. O sistema salva as informações e as funcionalidades dos aparelhos são armazenadas no banco de dados. | 3. O sistema salva as informações e as funcionalidades dos aparelhos são armazenadas no banco de dados. | ||
− | |||
− | |||
'''Pós-condições''': Aparelhos de climatização cadastrados e prontos para serem usados. | '''Pós-condições''': Aparelhos de climatização cadastrados e prontos para serem usados. | ||
Linha 454: | Linha 445: | ||
4. O usuário volta para [http://wiki.sj.ifsc.edu.br/index.php/PJI29006-2015-1-Wiki_do_Projeto#CSU09 CSU09]. | 4. O usuário volta para [http://wiki.sj.ifsc.edu.br/index.php/PJI29006-2015-1-Wiki_do_Projeto#CSU09 CSU09]. | ||
− | |||
'''Fluxo Alternativo''' (1): Alteração no modo de controle do sistema. | '''Fluxo Alternativo''' (1): Alteração no modo de controle do sistema. | ||
Linha 492: | Linha 482: | ||
6. O usuário volta para [http://wiki.sj.ifsc.edu.br/index.php/PJI29006-2015-1-Wiki_do_Projeto#CSU09 CSU09]. | 6. O usuário volta para [http://wiki.sj.ifsc.edu.br/index.php/PJI29006-2015-1-Wiki_do_Projeto#CSU09 CSU09]. | ||
− | |||
'''Fluxo Alternativo''' (1): Alteração no modo de controle do sistema. | '''Fluxo Alternativo''' (1): Alteração no modo de controle do sistema. | ||
Linha 537: | Linha 526: | ||
'''Pós-condições''': Ventiladores ligados e funcionando conforme o usuário solicitou. | '''Pós-condições''': Ventiladores ligados e funcionando conforme o usuário solicitou. | ||
− | |||
− | |||
<center>[[Arquivo:UseCase_Diagram_System2.png| 650px]]</center> | <center>[[Arquivo:UseCase_Diagram_System2.png| 650px]]</center> | ||
Linha 648: | Linha 635: | ||
{{collapse bottom}} | {{collapse bottom}} | ||
− | |||
===Modelo de Domínio=== | ===Modelo de Domínio=== | ||
Linha 658: | Linha 644: | ||
==Desenvolvimento== | ==Desenvolvimento== | ||
− | ===Sincronização de Diretórios Utilizando Rsync=== | + | ===Plano de Desenvolvimento=== |
+ | |||
+ | A execução do projeto, dentro da disciplina de Projeto Integrador II de 2015.1, consistirá de 2 ciclos de desenvolvimentos. Ao final de cada ciclo, os conjuntos de requisitos funcionais abaixo devem ser satisfeitos: | ||
+ | |||
+ | {{collapse top | Ciclo 1}} | ||
+ | * RF01. O dispositivo móvel deve controlar a projeção de arquivos pelo projetor | ||
+ | ** RF01.1. O dispositivo móvel deve controlar o projetor (liga/desliga); | ||
+ | ** RF01.3. Manipular arquivos; | ||
+ | ** RF01.4. Passar slides para frente ou para trás; | ||
+ | ** RF01.5. Selecionar slide específico; | ||
+ | *** A partir do número do slide | ||
+ | |||
+ | * RF05. O sistema deve implementar um gerenciador de apresentações | ||
+ | ** RF05.1. Carregar arquivos | ||
+ | ** RF05.2. Indentificar salas e horários | ||
+ | ** RF05.4. Autenticar usuário | ||
+ | *** A partir de arquivo de usuário e senha | ||
+ | {{collapse bottom | Ciclo 1}} | ||
+ | {{collapse top | Ciclo 2}} | ||
+ | * RF01. O dispositivo móvel deve controlar a projeção de arquivos pelo projetor | ||
+ | ** RF01.2. Carregar arquivo independente da extensão | ||
+ | ** RF01.6. Congelar projetor | ||
+ | ** RF01.7. Mudar dispositivo que irá carregar e controlar os slides | ||
+ | ** RF01.8. Compartilhar slides com outros dispositivos da mesma rede | ||
+ | ** RF01.9. Utilizar zoom e barra de rolagem | ||
+ | * RF02. O dispositivo móvel deve controlar a iluminação da sala (controle de iluminação das lâmpadas) | ||
+ | ** RF02.6. Notificar problemas com lâmpadas | ||
+ | * RF05. O sistema deve implementar um gerenciador de apresentações | ||
+ | ** RF05.3. Verificar conflitos de agendamento | ||
+ | ** RF05.4. Autenticar usuário | ||
+ | *** completo | ||
+ | ** RF05.9. Manipular arquivos | ||
+ | {{collapse bottom | Ciclo 2}} | ||
+ | {{collapse top | Ciclos Posteriores / Implementações adicionais }} | ||
+ | * RF01. O dispositivo móvel deve controlar a projeção de arquivos pelo projetor | ||
+ | ** RF01.5. Selecionar slide específico | ||
+ | *** A partir de lista de slides ou Thumbs | ||
+ | ** RF01.9. Utilizar zoom e barra de rolagem | ||
+ | * RF02. O dispositivo móvel deve controlar a iluminação da sala (controle de iluminação das lâmpadas) | ||
+ | ** RF02.1. Fechar/Abrir cortinas | ||
+ | ** RF02.2. Ligar/Apagar lâmpadas individualmente | ||
+ | ** RF02.3. Mudar modo de operação | ||
+ | ** RF02.4. Dimerizar lâmpadas | ||
+ | ** RF02.5. Integração com sensor de presença e timer | ||
+ | * RF03. O dispositivo móvel deve controlar a climatização do ambiente | ||
+ | ** RF03.1. Ligar/desligar ar condicionado | ||
+ | ** RF03.2. Aumentar/diminuir a temperatura | ||
+ | ** RF03.3. Mudar modo de operação do ar condicionado | ||
+ | ** RF03.4. Abrir/fechar as janelas | ||
+ | ** RF03.5. Ligar/desligar os ventiladores/exaustores | ||
+ | ** RF03.6. Ativar Swing do ar condicionado | ||
+ | ** RF03.7. Ligar/desligar aquecedores | ||
+ | ** RF03.8. Aumentar/diminuir temperatura dos aquecedores | ||
+ | * RF04. O Sistema deve implementar um controle da acesso ao meio (sala) | ||
+ | * RF05. O sistema deve implementar um gerenciador de apresentações | ||
+ | ** RF05.5. Organizar arquivos em grupos (disciplina) | ||
+ | ** RF05.6. Importar/Exportar agendamentos | ||
+ | ** RF05.7. Gerenciar cotas para arquivos | ||
+ | ** RF05.8. Compartilhar arquivos com outros usuários | ||
+ | {{collapse bottom | Ciclos Posteriores / Implementações adicionais }} | ||
+ | |||
+ | === Estudo das Tecnologias === | ||
+ | ====Sincronização de Diretórios Utilizando Rsync==== | ||
{{collapse top| Sincronização de Diretórios Utilizando Rsync [1] - Solução Obsoleta }} | {{collapse top| Sincronização de Diretórios Utilizando Rsync [1] - Solução Obsoleta }} | ||
Linha 1 283: | Linha 1 331: | ||
# and files in /etc/cron.d. These files also have username fields, | # and files in /etc/cron.d. These files also have username fields, | ||
# that none of the other crontabs do. | # that none of the other crontabs do. | ||
− | + | ||
SHELL=/bin/sh | SHELL=/bin/sh | ||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin | ||
− | + | ||
# m h dom mon dow user command | # m h dom mon dow user command | ||
17 * * * * root cd / && run-parts --report /etc/cron.hourly | 17 * * * * root cd / && run-parts --report /etc/cron.hourly | ||
Linha 1 292: | Linha 1 340: | ||
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) | 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) | ||
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) | 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) | ||
− | 00 23 * * 1-5 | + | 00 23 * * 1-5 webba sh /opt/webba/srv/cfg/script/removels.sh |
+ | 25 5 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
+ | 5 7 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
+ | 20 9 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
+ | 5 13 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
+ | 20 15 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
+ | 5 18 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
+ | 20 20 * * 1-5 webba sh /opt/webba/srv/cfg/script/chama_agendamento.sh | ||
# | # | ||
− | |||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
{{collapse bottom}} | {{collapse bottom}} | ||
Linha 1 325: | Linha 1 378: | ||
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) | 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) | ||
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) | 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) | ||
− | 00 23 | + | 00 23 * * 1-5 root sh /s001/cfg/script/remove_hardlink.sh |
− | 30 5 1-5 | + | 30 5 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
− | 10 7 1-5 | + | 10 7 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
− | 25 9 1-5 | + | 25 9 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
− | 10 13 1-5 | + | 10 13 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
− | 25 15 1-5 | + | 25 15 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
− | 10 18 1-5 | + | 10 18 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
− | 25 20 1-5 | + | 25 20 * * 1-5 root sh /s001/cfg/script/cliente_rsync.sh |
*/1 * * * * root / sh /s001/cfg/script/ntp.sh | */1 * * * * root / sh /s001/cfg/script/ntp.sh | ||
# | # | ||
Linha 1 382: | Linha 1 435: | ||
{{collapse bottom}} | {{collapse bottom}} | ||
− | ===Exibição de PDF com xpdf em Virtual Display=== | + | ====Exibição de PDF com xpdf em Virtual Display==== |
{{collapse top | Exibição de PDF com xpdf em Virtual Display [1] - Solução obsoleta, substituída por [2]}} | {{collapse top | Exibição de PDF com xpdf em Virtual Display [1] - Solução obsoleta, substituída por [2]}} | ||
Linha 1 716: | Linha 1 769: | ||
{{collapse bottom | Exibição de PDF com xpdf em Virtual Display [2] - Solução obsoleta, substituída por [3]l}} | {{collapse bottom | Exibição de PDF com xpdf em Virtual Display [2] - Solução obsoleta, substituída por [3]l}} | ||
− | {{collapse top | Exibição de PDF com xpdf em Virtual Display [3] - Solução | + | {{collapse top | Exibição de PDF com xpdf em Virtual Display [3] - Solução obsoleta, substituida pelo Web Service}} |
Como parte do ''Detalhamento da Especificação'' referente ao Ciclo 1 de desenvolvimento foi estudada a projeção de processos que utilizem interface gráfica em um virtual display, com ênfase na exibição de arquivos PDF através do visualizador [http://www.foolabs.com/xpdf/ xpdf] e envio de comandos através de um terminal para uma sessão remota da aplicação. | Como parte do ''Detalhamento da Especificação'' referente ao Ciclo 1 de desenvolvimento foi estudada a projeção de processos que utilizem interface gráfica em um virtual display, com ênfase na exibição de arquivos PDF através do visualizador [http://www.foolabs.com/xpdf/ xpdf] e envio de comandos através de um terminal para uma sessão remota da aplicação. | ||
Linha 1 938: | Linha 1 991: | ||
#!/bin/bash | #!/bin/bash | ||
− | + | echo "/bin/bash -c 'xpdf -fullscreen -remote servidor ${HOME}/$1 &'" > $HOME/pipe | |
</syntaxhighlight> | </syntaxhighlight> | ||
Linha 1 950: | Linha 2 003: | ||
#!/bin/bash | #!/bin/bash | ||
− | + | echo "/bin/bash -c 'xpdf.real -remote servidor -exec nextPage &'" > $HOME/pipe | |
</syntaxhighlight> | </syntaxhighlight> | ||
Linha 1 960: | Linha 2 013: | ||
#!/bin/bash | #!/bin/bash | ||
− | + | echo "/bin/bash -c 'xpdf.real -remote servidor -exec prevPage &'" > $HOME/pipe | |
</syntaxhighlight> | </syntaxhighlight> | ||
Linha 1 970: | Linha 2 023: | ||
#!/bin/bash | #!/bin/bash | ||
− | + | echo "/bin/bash -c 'xpdf.real -remote servidor -exec gotoPage\($1\) &'" > $HOME/pipe | |
</syntaxhighlight> | </syntaxhighlight> | ||
Linha 1 980: | Linha 2 033: | ||
#!/bin/bash | #!/bin/bash | ||
− | + | echo "/bin/bash -c 'xpdf.real -remote servidor -exec quit &'" > $HOME/pipe | |
</syntaxhighlight> | </syntaxhighlight> | ||
Linha 1 988: | Linha 2 041: | ||
{{collapse bottom | Scrits dos Comandos}} | {{collapse bottom | Scrits dos Comandos}} | ||
− | {{collapse bottom | Exibição de PDF com xpdf em Virtual Display [3] - Solução | + | {{collapse bottom | Exibição de PDF com xpdf em Virtual Display [3] - Solução obsoleta, substituida pelo Web Service}} |
− | ===Estudo da Raspberry Pi B+=== | + | ====Estudo da Raspberry Pi B+==== |
{{collapse top | Auto Login}} | {{collapse top | Auto Login}} | ||
Linha 2 154: | Linha 2 207: | ||
{{collapse bottom | Utilizar internet na raspberry através de rede via Ubuntu}} | {{collapse bottom | Utilizar internet na raspberry através de rede via Ubuntu}} | ||
− | ===API Web-Service a ser implementado na Raspberry Pi B+=== | + | ===API's de implementação=== |
+ | ====API Web-Service a ser implementado na Raspberry Pi B+==== | ||
+ | |||
+ | {{collapse top | API Web-Service a ser implementado na Raspberry Pi B+}} | ||
{| class="wikitable" | {| class="wikitable" | ||
Linha 2 160: | Linha 2 216: | ||
!scope="col"| URI | !scope="col"| URI | ||
!scope="col"| Parâmetros | !scope="col"| Parâmetros | ||
− | !scope="col"| Retorno | + | !scope="col"| Retorno em Sucesso |
+ | !scope="col"| Retorno em Fracasso | ||
!scope="col"| Descrição | !scope="col"| Descrição | ||
|- | |- | ||
− | |@GET || / | + | |@GET || /projetar || <center>-</center> || <center> [{"nome":"arquivo1.pdf","numeroPaginas":2},{"nome":"arquivo2.opt","numeroPaginas":33}] </center> || <center> [{'resultado': False}] </center> || Retorna os arquivos aos quais o usuário tem acesso e informações sobre os mesmos |
|- | |- | ||
− | |@GET || / | + | |@GET || /projetar/{''arquivo''} || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Inicia a projeção do ''arquivo'' solicitado pelo usuário |
|- | |- | ||
− | |@GET || /projetar | + | |@GET || /projetar/{''arquivo''}/avancarProjecao || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Faz a projeção da apresentação avançar um slide de ''arquivo'' |
|- | |- | ||
− | |@GET || /projetar | + | |@GET || /projetar/{''arquivo''}/retrocederProjecao || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Faz a projeção da apresentação retroceder um slide de ''arquivo'' |
|- | |- | ||
− | |@GET || /projetar | + | |@GET || /projetar/{''arquivo''}/saltarProjecao/{''numeroPagina''}|| <syntaxhighlight lang=java> String nomeDoArquivo |
− | int numeroPagina </syntaxhighlight> || < | + | int numeroPagina </syntaxhighlight> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Vai a uma determinada página de ''arquivo'' |
|- | |- | ||
− | |@GET || /projetar | + | |@GET || /projetar/{''arquivo''}/fechar || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Fecha a apresentação de ''arquivo'' |
|- | |- | ||
− | |@GET || /projetar | + | |@GET || /projetar/{''arquivo''}/obterThumb/{''thumb''} || <syntaxhighlight lang=java>String nomeDoArquivo |
− | int | + | int thumb </syntaxhighlight>|| <center> [{"thumb":arquivo-1.jpg}] </center> || <center> [{'resultado': False}] </center> || Retorna um determinado thumb (identificado por ''thumb'') referente ao ''arquivo'' |
|- | |- | ||
− | |@GET || /sincronizacao/forcaSincronizacao || - || < | + | |@GET || /sincronizacao/forcaSincronizacao || <center>-</center> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center>|| Força uma sincronização com o servidor de arquivos |
+ | |- | ||
+ | |@GET || <font color=darkred>/projetar/ligarProjetor</font> || <center> - </center> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Liga o projetor | ||
+ | |- | ||
+ | |@GET || <font color=darkred>/projetar/desligarProjetor</font> || <center> - </center> || <center> [{'resultado': True}] </center> || <center> [{'resultado': False}] </center> || Desliga o projetor | ||
|} | |} | ||
+ | |||
+ | {{collapse bottom | API Web-Service a ser implementado na Raspberry Pi B+}} | ||
+ | |||
+ | ====API Web-Service a ser implementado no GUI==== | ||
+ | |||
+ | {{collapse top | API Web-Service a ser implementado no GUI}} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | !scope="col"| Método | ||
+ | !scope="col"| URI | ||
+ | !scope="col"| Parâmetros | ||
+ | !scope="col"| Retorno (Json) | ||
+ | !scope="col"| Descrição | ||
+ | |||
+ | |- | ||
+ | |@POST || /auth || <syntaxhighlight lang=java> String usuario </syntaxhighlight> <syntaxhighlight lang=java> String senha </syntaxhighlight> || <syntaxhighlight lang=java> boolean resposta </syntaxhighlight>|| Caso seja possível criar o usúario, o servidor retorna a confirmação. Caso não mande os dados corretamente, retorna que não foi possível criar um usuário. | ||
+ | |- | ||
+ | |@POST || /auth || <syntaxhighlight lang=java> String usuario </syntaxhighlight> <syntaxhighlight lang=java> String senha </syntaxhighlight> || <syntaxhighlight lang=java> boolean resposta </syntaxhighlight>|| Retorna acesso permitido, caso os dados que o usuário tenha enviado, estiverem corretos, caso contrário acesso é negado. | ||
+ | |- | ||
+ | |@PUT || /change_passwd || <syntaxhighlight lang=java> String usuário </syntaxhighlight> <syntaxhighlight lang=java> String senha_atual </syntaxhighlight> <syntaxhighlight lang=java> String senha_nova </syntaxhighlight> || <syntaxhighlight lang=java> boolean resposta </syntaxhighlight> || Retorna se foi possível alterar a senha do usuário, caso contrário a senha antiga permanece. | ||
+ | |- | ||
+ | |@POST || /auth/{pasta} || <syntaxhighlight lang=java> String nomeDaPasta </syntaxhighlight> || <syntaxhighlight lang=java> int resposta </syntaxhighlight>|| Caso seja possível criar a subpasta, então o servidor retorna uma confirmação, informando que a pasta foi criada. Caso contrário o servidor, avisa que não foi possível. | ||
+ | |- | ||
+ | |@DELETE || /auth/{pasta} || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <syntaxhighlight lang=java> int resposta </syntaxhighlight>|| Caso a pasta exista, então o servidor retorna uma confirmação, informando que a pasta foi excluida. Caso contrário o servidor, avisa que não foi possível. | ||
+ | |- | ||
+ | |@GET || /arquivos/{user} || <syntaxhighlight lang=java> String nomeDoUsuário </syntaxhighlight> || <syntaxhighlight lang=java> Lista listaDeArquivos </syntaxhighlight>|| Caso o usuário exista, então o servidor retorna uma lista com todos os arquivos do usuário. Caso contrário o servidor, avisa que não foi possível. | ||
+ | |- | ||
+ | |@POST || /arquivos/{nome} || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <syntaxhighlight lang=java> int resposta </syntaxhighlight>|| Caso seja possível fazer upload do arquivo, então o servidor retorna uma confirmação, informando que o arquivo foi colocado corretamente na pasta do usuário. Caso contrário o servidor, avisa que ocorreu um erro durante o upload do arquivo. | ||
+ | |- | ||
+ | |@DELETE || /arquivos/{nome} || <syntaxhighlight lang=java> String nomeDoArquivo </syntaxhighlight> || <syntaxhighlight lang=java> int resposta </syntaxhighlight>|| Se o arquivo existir, então o servidor retorna uma confirmação,informando que foi removido arquivo foi removido com sucesso. Caso contrário servidor, avisa que não foi possível. | ||
+ | |- | ||
+ | |@POST || /agendamento/{user}/{nome} || <syntaxhighlight lang=java> String sala </syntaxhighlight> <syntaxhighlight lang=java> String arquivo </syntaxhighlight> <syntaxhighlight lang=java> String dia </syntaxhighlight> <syntaxhighlight lang=java> String mes </syntaxhighlight> <syntaxhighlight lang=java> String ano </syntaxhighlight> <syntaxhighlight lang=java> String hora </syntaxhighlight> <syntaxhighlight lang=java> String minuto </syntaxhighlight> || <syntaxhighlight lang=java> int resposta </syntaxhighlight> || Se o usuário informar corretamente: a sala, arquivo, data, então o servidor retorna uma confirmação, informando que foi feito com sucesso, caso contrário informa que não foi possível agendar a aula. | ||
+ | |- | ||
+ | |@DELETE || /deletar/{user}|| <syntaxhighlight lang=java> String usuario </syntaxhighlight> <syntaxhighlight lang=java> String senha </syntaxhighlight> || <syntaxhighlight lang=java> int resposta </syntaxhighlight> || Se for o próprio usuário que deseja se remover, então o servidor retorna uma confirmação, informando que foi removido com sucesso. Caso contrário servidor, avisa que não foi possível. | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | {{collapse bottom | API Web-Service a ser implementado no GUI}} | ||
+ | |||
+ | === Implementação do Web Service na Raspberry === | ||
+ | |||
+ | {{collapse top | Instalação dos componentes necessários}} | ||
+ | ==== 1. [http://www.foolabs.com/xpdf/ Xpdf] ==== | ||
+ | Visualizador de [http://pt.wikipedia.org/wiki/Portable_document_format PDF's]. | ||
+ | <syntaxhighlight lang=bash> $ sudo apt-get install xpdf </syntaxhighlight> | ||
+ | ==== 2. [https://www.python.org/ Python]==== | ||
+ | Linguagem de programação utilizada na implementação do web service. | ||
+ | <syntaxhighlight lang=bash> $ sudo apt-get install python </syntaxhighlight> | ||
+ | ==== 3. [https://pypi.python.org/pypi/pip Python-pip] ==== | ||
+ | Gerenciador de extensões python. | ||
+ | <syntaxhighlight lang=bash> $ sudo apt-get install python-pip </syntaxhighlight> | ||
+ | ==== 4. [https://mail.python.org/mailman/listinfo/python-dev Python-dev] ==== | ||
+ | Pacote python para desenvolvedores. | ||
+ | <syntaxhighlight lang=bash> $ sudo apt-get install python-dev </syntaxhighlight> | ||
+ | ==== 5. Framework [http://flask.pocoo.org/ Flask] ==== | ||
+ | Framework utilizado na implementação de web services. | ||
+ | <syntaxhighlight lang=bash> $ sudo pip install flask </syntaxhighlight> | ||
+ | ==== 6. Extensão [https://flask-httpauth.readthedocs.org/en/latest/ HTTPAuth] do Flask ==== | ||
+ | Para autenticação via HTTP. | ||
+ | <syntaxhighlight lang=bash> $ sudo pip install flask-httpauth </syntaxhighlight> | ||
+ | ==== 7. Extensão [https://pypi.python.org/pypi/netifaces netifaces] para Python ==== | ||
+ | Fornece informações sobre as interfaces de conexão. | ||
+ | <syntaxhighlight lang=bash> $ wget https://pypi.python.org/packages/source/n/netifaces/netifaces-0.10.4.tar.gz | ||
+ | $ tar xvzf netifaces-0.10.4.tar.gz | ||
+ | $ cd netifaces-0.10.4 | ||
+ | $ python setup.py install </syntaxhighlight> | ||
+ | ==== 8. Extensão [https://pypi.python.org/pypi/Flask-Cors/1.10.3 Cors] do Flask ==== | ||
+ | Devido a '''[https://pt.wikipedia.org/wiki/Pol%C3%ADtica_de_mesma_origem política de mesma origem] (same origin policy)''', configurada como padrão nos servidores, qualquer requisição feita de diferentes domínios é bloqueada pelos navegadores, isto impede que ataques de [https://pt.wikipedia.org/wiki/Cross-site_scripting Cross-domain] sejam feitos. A habilitação da extensão '''[https://pt.wikipedia.org/wiki/Cross-origin_resource_sharing CORS] (cross-origin resource sharing)''' cria um caminho para que estas requisições sejam feitas de uma maneira mais segura, sem que todas as requisições deste tipo sejam habilitadas. Para habilitar os CORS é necessário primeiramente instalar a biblioteca para o suporte do CORS no servidor. | ||
+ | |||
+ | <code> $ pip install -U flask-cors </syntaxhighlight> | ||
+ | |||
+ | Depois é necessário apenas a importação da biblioteca e inserir o código para habilitar o CORS nos recursos do servidor. | ||
+ | |||
+ | <syntaxhighlight lang=python> | ||
+ | from flask.ext.cors import CORS | ||
+ | |||
+ | app = Flask(__name__) | ||
+ | cors = CORS(app) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ====9. Instalação do cec-utils, que utiliza a biblioteca [https://github.com/Pulse-Eight/libcec libcec] ==== | ||
+ | Para envio de comandos para dispositivos conectados via [http://www.infowester.com/hdmi.php HDMI] | ||
+ | |||
+ | <syntaxhighlight lang=bash> sudo apt-get install cec-utils </syntaxhighlight> | ||
+ | |||
+ | {{collapse bottom | Instalação dos componentes necessários}} | ||
+ | |||
+ | {{collapse top | Implementação do Web Service}} | ||
+ | |||
+ | *Assume-se que o diretório dos usuários estará localizado no diretório do usuário '''root''' da raspberry (/root), e que no diretório de cada usuário haverá um diretório chamado ''thumbs'', que conterá todas as miniaturas necessárias para exibição no dispositivo móvel. | ||
+ | |||
+ | <syntaxhighlight lang=python> | ||
+ | #!/usr/bin/python | ||
+ | |||
+ | __author__ = "Matuzalem - Projeto Integrador II - Engenharia de Telecomunicacoes - Junho de 2015" | ||
+ | __date__ = "$11/06/2015 01:09:22$" | ||
+ | |||
+ | import sys | ||
+ | import netifaces # para capturar a interface do servidor automaticamente, caso insira manualmente o ip do servidor e descartavel, desde que comente as linhas de codigo equivalentes | ||
+ | from flask import Flask, jsonify | ||
+ | from flask import abort | ||
+ | from flask import make_response | ||
+ | from flask import request | ||
+ | from flask import url_for | ||
+ | from flask import send_file # enviar arquivos thumbs pela rede | ||
+ | from flask.ext.httpauth import HTTPBasicAuth | ||
+ | from flask.ext.cors import CORS # habilita troca de informacoes cross domain | ||
+ | auth = HTTPBasicAuth() | ||
+ | |||
+ | import subprocess | ||
+ | import os | ||
+ | |||
+ | app = Flask(__name__) | ||
+ | cors = CORS(app) | ||
+ | |||
+ | # Este servidor foi desenvolvido considerando a estrutura /root/User para o armazenamento de pdfs na raspberry | ||
+ | #####################[DEVE SER PREENCHIDO]############################ | ||
+ | usuario = 'User' # usuario conectado a raspberry | ||
+ | interface='lo' # interface em que o servidor funcionara, para obter o ip automaticamente | ||
+ | porta=5000 # porta em que o servidor ouvira | ||
+ | ###################################################################### | ||
+ | caminho = "" # diretorio onde esta localizado o diretorio do usuario | ||
+ | pastaUsuario = "" # diretorio usuario | ||
+ | numeroPaginas="" # numero de paginas do arquivo | ||
+ | paginaAtual="" # pagina atual do arquivo | ||
+ | |||
+ | ### Como listar arquivos em diretorio e seus subdiretorios ### | ||
+ | # curl -i http://localhost:5000/projetar | ||
+ | # Lista os arquivos do tipo pdf em /root/{usuario}/ e o numero de paginas de cada arquivo | ||
+ | @app.route('/projetar', methods=['GET']) | ||
+ | def obtem_arquivos(): | ||
+ | lista = [] | ||
+ | #https://docs.python.org/2/library/os.html | ||
+ | for root, dirs, files in os.walk(caminho+usuario+'/'): | ||
+ | for nome in files: | ||
+ | if nome.endswith(".pdf"): | ||
+ | path = os.path.join(root, nome) | ||
+ | size = os.stat(path).st_size # in bytes | ||
+ | linha = {} | ||
+ | linha['numeroPaginas'] = subprocess.check_output("/usr/bin/pdfinfo "+path+" | grep -oP '(?<=Pages: )[ A-Za-z0-9]*'", shell=True)[:-1] # [:-1] remove o ultimo elemento do vetor, no caso \n | ||
+ | linha['nome'] = nome | ||
+ | lista.append(linha) | ||
+ | return jsonify({'arquivos': lista}), 200 | ||
+ | |||
+ | |||
+ | ############################ Auxiliares ############################## | ||
+ | |||
+ | # verifica se um arquivo existe em um determinado diretorio | ||
+ | def verifica_existencia(diretorio, arquivo): | ||
+ | if (os.path.exists(diretorio+arquivo) == True): | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | ######################### Metodos do XPDF ############################ | ||
+ | # curl -i http://localhost:5000/projetar/{arquivo.pdf} | ||
+ | # Abre um pdf | ||
+ | @app.route('/projetar/<arquivo>', methods=['GET']) | ||
+ | def abre_pdf(arquivo): | ||
+ | # Chamada de processo nao bloqueante - fica em background | ||
+ | local = pastaUsuario+arquivo | ||
+ | if (verifica_existencia(pastaUsuario,arquivo) == True): | ||
+ | p1 = os.spawnlp(os.P_NOWAIT,"xpdf","/usr/bin/xpdf","-fullscreen","-remote", arquivo, local) | ||
+ | # /usr/bin/pdfinfo /root/User/arquivo.pdf | grep -oP '(?<=Pages: )[ A-Za-z0-9]*' | ||
+ | # verifica o numero de paginas do pdf | ||
+ | global numeroPaginas | ||
+ | global paginaAtual | ||
+ | numeroPaginas = subprocess.check_output("/usr/bin/pdfinfo "+local+" | grep -oP '(?<=Pages: )[ A-Za-z0-9]*'", shell=True) | ||
+ | paginaAtual = 1 | ||
+ | return jsonify({'resultado': True}), 200 | ||
+ | else: | ||
+ | print 'Usuario '+usuario+' tentou acessar o arquivo '+arquivo+' inexistente!' | ||
+ | return jsonify({'resultado': False}), 404 | ||
+ | |||
+ | # curl -i http://localhost:5000/projetar/{arquivo.pdf}/avancarProjecao | ||
+ | # Avanca uma pagina | ||
+ | @app.route('/projetar/<arquivo>/avancarProjecao', methods=['GET']) | ||
+ | def avanca_pagina(arquivo): | ||
+ | comando = 'nextPage' | ||
+ | global paginaAtual | ||
+ | if(int(paginaAtual) < int(numeroPaginas)): | ||
+ | # chamada de processo bloqueante, porem o xpdf termina logo apos a execucao | ||
+ | paginaAtual = paginaAtual + 1 | ||
+ | p = subprocess.call(['xpdf.real','-remote',arquivo,'-exec', comando]) | ||
+ | return jsonify({'resultado': True}), 200 | ||
+ | else: | ||
+ | print 'Usuario '+usuario+' tentou acessar a pagina '+str(paginaAtual+1)+' do pdf '+pastaUsuario+arquivo+' inexistente!' | ||
+ | return jsonify({'resultado': False}), 404 | ||
+ | |||
+ | # curl -i http://localhost:5000/projetar/{arquivo.pdf}/retrocederProjecao | ||
+ | # Retrocede uma pagina | ||
+ | @app.route('/projetar/<arquivo>/retrocederProjecao', methods=['GET']) | ||
+ | def retrocede_pagina(arquivo): | ||
+ | if(int(paginaAtual) > 1): | ||
+ | comando = 'prevPage' | ||
+ | # chamada de processo bloqueante, porem o xpdf termina logo apos a execucao | ||
+ | subprocess.call(['xpdf.real','-remote',arquivo,'-exec', comando]) | ||
+ | return jsonify({'resultado': True}), 200 | ||
+ | else: | ||
+ | print 'Usuario '+usuario+' tentou acessar a pagina '+str(paginaAtual-1)+' do pdf '+pastaUsuario+arquivo+' inexistente!' | ||
+ | return jsonify({'resultado': False}), 404 | ||
+ | |||
+ | # curl -i http://localhost:5000/projetar/{arquivo.pdf}/saltarProjecao/{numPagina} | ||
+ | # Avanca para uma pagina do pdf, se a pagina nao existir retorna um codigo de erro | ||
+ | @app.route('/projetar/<arquivo>/saltarProjecao/<int:pagina>', methods=['GET']) | ||
+ | def salta_paginas(arquivo,pagina): | ||
+ | global paginaAtual | ||
+ | if(pagina <= int(numeroPaginas) and (int(pagina) > 0)): | ||
+ | comando = 'gotoPage('+str(pagina)+')' | ||
+ | # chamada de processo bloqueante, porem o xpdf termina logo apos a execucao | ||
+ | subprocess.call(['xpdf.real','-remote',arquivo,'-exec',comando]) | ||
+ | paginaAtual = pagina | ||
+ | return jsonify({'resultado': True}), 200 | ||
+ | else: | ||
+ | print 'Usuario '+usuario+' tentou acessar a pagina '+str(pagina)+' do pdf '+pastaUsuario+arquivo+' inexistente!' | ||
+ | return jsonify({'resultado': False}), 404 | ||
+ | |||
+ | |||
+ | # curl -i http://localhost:5000/projetar/{arquivo.pdf}/fechar | ||
+ | # Fechar projecao | ||
+ | @app.route('/projetar/<arquivo>/fechar', methods=['GET']) | ||
+ | def fechar_projecao(arquivo): | ||
+ | comando = 'quit' | ||
+ | global paginaAtual | ||
+ | global numeroPaginas | ||
+ | paginaAtual = numeroPaginas = "" | ||
+ | # chamada de processo bloqueante, porem o xpdf termina logo apos a execucao | ||
+ | subprocess.call(['xpdf.real','-remote',arquivo,'-exec', comando]) | ||
+ | return jsonify({'resultado': True}), 200 | ||
+ | |||
+ | ###################### OBTEM THUMB ########################## | ||
+ | |||
+ | # curl -i http://localhost:5000/projetar/{arquivo.pdf}/obterThumb/{thumb} | ||
+ | # Retorna um thumb do tipo jpg identificado por {arquivo}-{thumb}.jpg | ||
+ | @app.route('/projetar/<arquivo>/obterThumb/<int:thumb>', methods=['GET']) | ||
+ | def obter_thumb(arquivo, thumb): | ||
+ | if((thumb < int(numeroPaginas)) & (thumb >= 0)): | ||
+ | fileName, fileExtension = os.path.splitext(arquivo) | ||
+ | caminhoArquivo = pastaUsuario+'thumbs/'+fileName+'-'+(str(thumb))+'.jpg' | ||
+ | return send_file(caminhoArquivo, mimetype='image/jpg') | ||
+ | else: | ||
+ | caminhoArquivo = pastaUsuario+'thumbs/'+'erro.jpg' | ||
+ | return send_file(caminhoArquivo, mimetype='image/jpg') | ||
+ | |||
+ | ###########COMANDOS DE CONTROLE DE PROJECAO################## | ||
+ | ############OS COMANDOS NAO ESTAO FUNCIONAIS########################## | ||
+ | # curl -i http://localhost:5000/projetar/ligarProjetor | ||
+ | # Retrocede uma pagina | ||
+ | #@app.route('/projetar/ligarProjetor, methods=['GET']) | ||
+ | #def liga_projetor(): | ||
+ | # subprocess.call(['echo "standby 0" | cec-client -s']) | ||
+ | # return jsonify({'resultado': True}), 200 | ||
+ | |||
+ | # curl -i http://localhost:5000/projetar/desligarProjetor | ||
+ | # Retrocede uma pagina | ||
+ | #@app.route('/projetar/desligarProjetor, methods=['GET']) | ||
+ | #def desliga_projetor(): | ||
+ | # subprocess.call(['echo "on 0" | cec-client -s']) | ||
+ | # return jsonify({'resultado': True}), 200 | ||
+ | ############################################################### | ||
+ | |||
+ | @app.errorhandler(404) ## Tratamento de erro | ||
+ | def not_found(error): | ||
+ | return make_response(jsonify({'Erro': 'Recurso nao encontrado!'}), 404) | ||
+ | |||
+ | ############################################################## | ||
+ | |||
+ | if __name__ == "__main__": | ||
+ | print "Servidor no ar!" | ||
+ | caminho = os.path.expanduser('~')+'/' # obtem o diretorio do usuario do SO | ||
+ | pastaUsuario = caminho+usuario+'/' # obtem o diretorio do usuario conectado (User) | ||
+ | ip = netifaces.ifaddresses(interface)[2][0]['addr'] # obtem o ip referente a interface | ||
+ | app.run(debug=True,host=ip,port=porta) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | *Considerando a instalação correta dos componentes e que o arquivo seja salvo com o nome <font color=darkred> servidor.py </font> basta executar o web service com o comando: | ||
+ | <syntaxhighlight lang=bash> python servidor.py </syntaxhighlight> | ||
+ | |||
+ | {{collapse bottom | Implementação do Web Service}} | ||
+ | |||
+ | ==Resultados obtidos na implementação do projeto== | ||
+ | |||
+ | Nessa etapa final, cada integrante do grupo ficou responsável por uma parte do projeto. Sendo que as partes individuais da maioria funcionaram, mas tivemos alguns problemas na parte da integração. relataremos abaixo as partes do trabalho que funcionaram e as que tivemos problemas. | ||
+ | |||
+ | * Obtivemos sucesso na parte de manipulação dos slides colocados na raspberry, nessa parte conseguíamos via uma aplicação no celular, avançar ou retroceder nos slides. Só tínhamos uma pequena demora na passagem, pelo fato da demora no processamento das imagens. | ||
+ | |||
+ | * As partes das aplicações visualizadas pelo usuário, no website, funcionaram em partes: | ||
+ | ** Conseguimos fazer a autenticação dos usuários, porém não foi possível manter a conexão do usuário | ||
+ | ** A parte do Upload dos arquivos funcionou perfeitamente, porém como não conseguimos manter a conexão, tivemos que criar um usuário fictício, para assim colocarmos os arquivos na pasta desse usuário, só ressaltamos que não foi implementado a exclusão de arquivos, isso foi deixado para o ciclo 2, que seria para o projeto de ideias inovadoras | ||
+ | ** O agendamento dos arquivos foi feito a parte que estava descrita para ser realizada no ciclo 1 do projeto, mas também tivemos o mesmo problema com o usuário, descrito anteriormente | ||
+ | ** Tivemos um pequeno problema na hora que fomos tentar realizar o rsync com a raspberry, com isso alteramos o script para relializar a sincronização dos dados. Não foi possível testar a integração completa do sistema Webba devido a problemas técnicos ocorrido no momento. Porém, este mesmo projeto foi inscrito no projeto Ideias Inovadoras do IFSC, caso consiga passar para a etapa de desenvolvimento do projeto a meta da equipe será implementar todos os requisitos propostos previamente para o projeto e torná-lo um produto. |
Edição atual tal como às 17h31min de 6 de julho de 2015
Sistema de Automatização de Sala de Aula
Esta página contém a documentação do projeto de uma Sala de Aula Inteligente, desenvolvido no contexto da disciplina de Projeto Integrador II da Engenharia de Telecomunicações do IFSC, no semestre 2015.1. Detalhes de execução do projeto podem ser encontrados nos links abaixo.
Descrição
O projeto consiste no desenvolvimento de um sistema de automatização de sala de aula, controlando o sistema de iluminação (lâmpadas), projeção e refrigeração (ar condicionado) do ambiente, a partir de um dispositivo móvel. Adicionalmente, propõe-se que o Sistema implemente um controle de acesso à sala, podendo ser efetuado através de um sistema de controle de acesso preexistente.
Análise
Levantamento de Requisitos
Funcionais:
Requisitos Funcionais |
---|
RF01. O dispositivo móvel deve controlar a projeção de arquivos pelo projetor;
RF02. O dispositivo móvel deve controlar a iluminação da sala (controle de iluminação das lâmpadas);
RF03. O dispositivo móvel deve controlar a climatização do ambiente
RF04. O Sistema deve implementar um controle da acesso ao meio (sala); RF05. O sistema deve implementar um gerenciador de apresentações
|
Não-funcionais
Requisitos Não-Funcionais |
---|
RNF01. Aunteticação: Apenas usuários com permissão podem acessar o Sistema; RNF02. Integridade: Usuário não pode editar arquivos de outros usuários e uma sala inteligente poderá ser comandada por um único por vez; RNF03. Desempenho e Eficiência: O Sistema possui um tempo de resposta máximo para cada instrução; RNF04. Conectividade: O Sistema deve utilizar a infra-estrutura de redes já disponível no campus; RNF05. Usabilidade: A interface do Sistema deve ser intuitiva; RNF06. Restrição de Custo: O projeto possui um orçamento de no máximo U$ 100,00 (cem dólares americanos); RNF07. Escalabilidade: O Sistema deve possuir a capacidade de expandir o número de salas inteligentes de uma maneira simples. RNF08. Portabilidade: Ausência de dependências de implementações específicas de tecnologias. |
Atores
Atores |
---|
1. Projetor: Sistema de Terceiro que projeta os arquivos. 2. Ar-condicionado: Sistema de Terceiro que tem por função controlar a climatização do ambiente. 3. Usuário: Indivíduo que tem permissão para controlar as funcionalidades do sistema. 4. Sensor de presença: Sistema de terceiro que detecta a presença de algum indivíduo no ambiente. 5. Ventilador: Sistema de terceiro que ventila o ambiente. 6. Lâmpada: Sistema de terceiro utilizado para iluminação do ambiente. 7. Banco de dados: Servidor para armazenar os dados e arquivos (slides) dos usuários. 8. Aquecedores: Sistema de terceiro que possui a mesma funcionalidade do 2º ator, porém só eleva a temperatura do ambiente. 9. Temporizador: Sistema de terceiro utilizado para iniciar ou encerar um evento. 10. Cortinas: Sistema de terceiro utilizado para adequar a iluminação do ambiente. 11. Controle de acesso ao meio: Sistema de terceiro utilizado para permitir o acesso ao ambiente. |
Casos de Uso
Descrição dos Casos de Uso |
---|
CSU01Cadastrar Projetor Sumário: Usuário cadastra o projetor que a sala possui. Ator Primário: Usuário Atores Secundários: Banco de dados Precondições: Usuário ter sido autenticado. Fluxo Principal 1. O sistema solicita que o usuário cadastre o dispositivo de projeção. 2. O usuário informa qual o dispositivo que pertence a sala. 3. O usuário nomeia o dispositivo de projeção 4. O sistema cadastra o dispositivo informado pelo usuário. 5. O usuário configura o dispositivo para cadastrar uma configuração default. 6. O sistema ajusta as funcionalidades do dispositivo configurado pelo usuário. Pós-condições: Dispositivo de projeção cadastrado e pronto para ser utilizado. CSU02Carregar Arquivo para Projetor Sumário: Usuário seleciona o arquivo que será carregado do banco de dados para o projetor. Ator Primário: Usuário Atores Secundários: Banco de dados Precondições: Usuário ter sido autenticado e ter cadastrado dispositivo de projeção. Fluxo Principal 1. O usuário seleciona no banco de dados qual o arquivo que será carregado, com auxílio de um dispositivo móvel. 2. O banco de dados envia para o projetor o arquivo que será exibido. Fluxo Alternativo (1): Arquivo não existe. a. O banco de dados envia uma mensagem para o usuário informando que o arquivo não existe e o usuário deve escolher outro arquivo ou carregar outro arquivo no banco de dados. Fluxo Alternativo (2): Mudar de dispositivo que irá carregar o arquivo. a. O usuário se autentica em outro dispositivo para carregar o arquivo Pós-condições: Arquivo carregado e sendo exibido pelo dispositivo de projeção CSU03Compartilhar Arquivo Sumário: Usuário seleciona o arquivo que será compartilhado com outros usuários que assistem à apresentação. Ator Primário: Bando de dados Atores Secundários: Outros usuários Precondições: Usuário ter sido autenticado, ter cadastrado dispositivo de projeção e ter carregado o arquivo. Fluxo Principal 1. O banco dados disponibiliza o QR code do arquivo para os usuários. 2. Os outros usuários escaneam o QR code (utilizando um aplicativo próprio para isso) do arquivo e fazem download. Fluxo Exceção (1): Sem acesso ao banco de dados. a. O download poderá ser fornecido em outro momento quando o bancos de dados estiver disponível. Pós-condições: Arquivo compartilhado com todos os usuários autenticados. CSU04Controlar Projetor Sumário: Usuário utiliza o sistema para controlar o projetor. Ator Primário: Usuário Atores Secundários: Projetor Precondições: Usuário ter sido autenticado, ter cadastrado dispositivo de projeção e ter carregado o arquivo. Fluxo Principal 1. O usuário solicita que o projetor seja ligado, com auxílio do dispositivo móvel. 2. O sistema configura o projetor de acordo com as solicitações do usuário realizadas no CSU01. 3. O usuário pode passar para frente ou para trás os slides. 4. O usuário seleciona um slide específico. 5. O usuário congela a projeção de slides. 6. O usuário utiliza a barra de rolagem ou zoom para melhorar a visualização do slide. Fluxo Exceção (1): Lâmpada do projetor queimada. a. O sistema envia uma mensagem ao usuário informando que deve trocar a lâmpada do projetor. Fluxo Alternativo (1): Mudar dispositivo que irá controlar o dispositivo de projeção. a. Usuário se autentica em outro dispositivo e passa à manipular o arquivo no novo dispositivo, sem a necessidade de voltar aos casos de uso, CSU01, ou CSU02, ou ainda CSU03. Fluxo Alternativo (2): Manipular arquivos. a. Usuario seleciona outro arquivo à ser projetado, o sistema deve executar o CSU02. Pós-condições: Projetor ligado e funcionando de acordo como o usuário solicitou CSU05Cadastro da sala e dos modos de operação Sumario: usuário cadastrar os modos de operação de cada sala. Ator principal: usuário. Ator secundário: banco de dados Precondições: o usuário já teve estar autentificado pelo sistema. Fluxo Principal. 1. O sistema pede para cadastrar as lâmpadas e cortinas da sala. 2. Usuário informa os números de cortinas e lâmpadas. 3. Usuário cadastra as características de cada lâmpada. 4. Usuário nomeia cada lâmpada e cortina. 5.O sistema pede para cadastra os modos de operação de iluminação: cinema, aula e apresentação. 6. Usuário seleciona um modo para cadastrar. 7. Usuário indica quais lâmpadas ficaram acesa. 8.Usuário indica qual é a intensidade das lâmpadas acesa, caso se a lâmpada possui essa característica. . 9. Usuário indica em qual modo as cortinas devem ficar: aberta, fechada ou automática(as cortinas mudam sua inclinação a cada 15min, para aproveitar a luz natural). 10.Informações dos modos de operação são armazenado no banco de dados. CSU06Iluminação da sala Sumario: usuário deseja selecionar um modo de operação. Ator principal: usuário. Ator secundário: lâmpadas, cortinas e banco de dados . Precondições: o usuário já teve estar autentificado pelo sistema, as cortinas e as lâmpadas já devem estar cadastrada no sistema. Fluxo Principal 1. O sistema apresenta os quatro modos de operação de iluminação: cinema, aula , apresentação e o manual. 2. Usuário seleciona uma das opções. 3. O sistema ajusta cortinas e lâmpadas conforme o modo desejado. 4. Quando a aula acabar, o sistema deve executar caso de uso CSU07. Fluxo Alternativo (2): Modo de operação manual. a. Executar modo o caso de uso CSU08. Fluxo Alternativo (2): Alteração para override. a. O usuário liga ou desliga as lâmpadas pelo interruptor. b. O usuário ajusta a posição da cortina conforme sua escolha de forma manual Fluxo de Exceção (3): Lâmpada queimada. Caso alguma lâmpada queime, ocorre uma notificação para o sistema, para que possam substitui-la. CSU07Desligando a iluminação Sumario: desligando todas as luzes. Ator principal: usuário. Ator secundário: temporizador, sensor de presença, cortinas e lâmpadas. Precondições: o sensor de presença e temporiozador já devem estar cadastrada no sistema. Fluxo Principal 1.Após o término da aula, o sistema liga um temporizador por um determinado tempo. 2.Após de passar esse tempo o sensor de presença é ativado. 3.Sensor de presença não detecta a presença de uma pessoa na sala, assim toda iluminação da sala é desligada e as cortinas fechadas. Fluxo Alternativo (3): Ainda há pessoas na sala. a. Temporizador fica acionando o sensor de presença até que não haja ninguém na sala . CSU08Iluminação da sala no modo manual Sumario:usuário seleciona modo operação manual. Ator principal: usuário. Ator secundário :lâmpadas e cortinas. Precondições: o usuário já teve estar autentificado pelo sistema, as cortinas e as lâmpadas já devem estar cadastrada no sistema e usuário seleciona modo operação manual. Fluxo Principal 1. Sistema apresenta todas as lâmpadas da sala. 2. O usuário seleciona as lâmpadas que ele deseja acender. 3. O usuário seleciona as lâmpadas que ele deseja ajustar a sua intensidade, caso a lâmpada possui essa característica. 4. O usuário decide se quer abrir/fechar as cortinas da sala ou elas ficarem mo moto automático(as cortinas mudam sua inclinação a cada 15 minutos, para aproveitar a luz natural). 5. Execute caso de uso CSU07. Fluxo de Exceção (2): Lâmpada queimada. a.Caso alguma lampada queime, ocorre uma notificação para o sistema, para que possam substitui-la Fluxo Alternativo (2): Alteração para override. a. O usuário liga ou desliga as lâmpadas pelo interruptor. b. O usuário ajusta a posição da cortina conforme sua escolha de forma manual CSU09Climatizar Sumário: Usuário utiliza o sistema para ajustar a temperatura da sala. Ator Primário : Usuário. Ator Secundário: Ar condicionado, ventilador e aquecedor. Pré-condições: Usuário esta autenticado no sistema e aparelhos cadastrados no sistema. Fluxo Principal: 1. O sistema apresenta os aparelho de climatização disponíveis. 2. O usuário escolhe um dos aparelhos. 3. O usuário conforme sua escolha vai para um dos casos de uso, CSU11, CSU12 ou CSU13. 4. O sistema ajustas todas as funcionalidades dos aparelhos que o usuário escolheu. 5. O sistema continua funcionando normalmente.
a. O usuário solicitou ao sistema o desligamento do dispositivo de climatização. b. O sistema desliga o dispositivo. Pós-condições: Aparelhos de climatização ligado e funcionando conforme o usuário solicitou. CSU10Cadastrar Aparelhos Sumário: Usuário cadastra o número de aparelhos que a sala possui. Ator Primário : Usuário. Ator Secundário: Banco de dados. Pré-condições: Usuário esta autenticado no sistema. Fluxo Principal: 1. O usuário informa ao sistema quantos aparelhos de climatização terão na sala, como o número de ventiladores, ar condicionados e aquecedores. 2. O sistema cadastra todos os aparelhos informados pelo usuário e informa as características funcionais de cada aparelho. 3. O sistema salva as informações e as funcionalidades dos aparelhos são armazenadas no banco de dados. Pós-condições: Aparelhos de climatização cadastrados e prontos para serem usados. CSU11Controlar Aquecedores Sumário: Usuário utiliza o sistema para ajustar a temperatura da sala. Ator Primário : Usuário. Ator Secundário: Aquecedores e banco de dados. Pré-condições: Usuário esta autenticado no sistema e aparelhos cadastrados no sistema. Fluxo Principal: 1. O usuário solicita que o aquecedor seja ligado, com o auxílio do dispositivo móvel. 2. O sistema liga o aquecedor com uma temperatura padrão, essa que vai ser cadastrada nas configurações padrão que estarão armazenada no banco de dados. 3. O sistema solicita que as janelas e portas sejam fechadas. 4. O usuário volta para CSU09. Fluxo Alternativo (1): Alteração no modo de controle do sistema. a. O usuário pode ligar os dispositivos de climatização do modo convencional, ou seja, ouverride. Fluxo Alternativo (2): Alteração da temperatura do aparelho. a. O usuário escolhe uma temperatura do aquecedor. b. O sistema altera a temperatura do aparelho. Pós-condições: Aquecedor ligado e funcionando conforme o usuário solicitou. CSU12Controlar Ar Condionados Sumário: Usuário utiliza o sistema para ajustar a temperatura da sala. Ator Primário : Usuário. Ator Secundário: Ar condicionado e banco de dados. Pré-condições: Usuário esta autenticado no sistema e aparelhos cadastrados no sistema. Fluxo Principal 1. O usuário solicita que o ar condicionado seja ligado, com o auxílio do dispositivo móvel. 2. O sistema liga o ar condicionado com uma temperatura padrão, essa que vai ser cadastrada nas configurações padrão que estarão armazenada no banco de dados. 3. O sistema solicita que as janelas e portas sejam fechadas. 4. O sistema disponibiliza ao usuários os modos de operação, como ventilação, aquecimento, ativar swing ou modo turbo. 5. O usuário seleciona um dos modos de operação. 6. O usuário volta para CSU09. Fluxo Alternativo (1): Alteração no modo de controle do sistema. a. O usuário pode ligar os dispositivos de climatização do modo convencional, ou seja, override. Fluxo Alternativo (2): Alteração da temperatura do aparelho. a. O usuário escolhe uma temperatura do ar condicionado. b. O sistema altera a temperatura do aparelho. Pós-condições: Ar condicionado ligado e funcionando conforme o usuário solicitou. CSU013Controlar Ventiladores Sumário: Usuário utiliza o sistema para ajustar a temperatura da sala. Ator Primário : Usuário. Ator Secundário: Ventilador e banco de dados. Pré-condições: Usuário esta autenticado no sistema e os aparelhos cadastrados no sistema. Fluxo Principal: 1. O usuário solicita que os ventiladores sejam ligados, com o auxílio do dispositivo móvel. 2. O sistema liga os ventiladores com uma velocidade padrão, essa que vai ser cadastrada nas configurações padrão que estarão armazenada no banco de dados. 3. O sistema solicita que as janelas se abram. 4. O usuário volta para CSU09. Fluxo Alternativo (1): Alteração no modo de controle do sistema. a. O usuário pode ligar os dispositivos de climatização do modo convencional, ou seja, ouverride. Fluxo Alternativo (2): Alteração da velocidade do aparelho. a. O usuário solicita que a velocidade dos ventiladores sejam aumentadas.
CSU014Carregar Arquivo para o Banco de Dados Sumário: Usuário utiliza o banco de dados para armazenar o arquivo. Ator primário: Usuário. Ator Secundário: Banco de Dados. Pré-condição: Usuário está autenticado no sistema. Fluxo Principal: 1. O usuário carrega o arquivo no sistema. 2. O arquivo é armazenado no Banco de Dados. Fluxo de Exceção: Se o limite de armazenamento do usuário for atingido o sistema emitirá uma aviso sobre a impossibilidade de armazenar o arquivo. CSU015Autenticar Usuário Sumário: Autenticação do usuário no Sistema. Ator primário: Usuário. Ator secundário: Banco de Dados. Fluxo Principal: 1. O usuário conecta-se ao sistema. 2. O usuário fornece suas credenciais. 3. O sistema verifica se as credenciais são válidas, comparando-as com as guardadas no Banco de Dados. 4. O sistema confirma as credenciais do usuário. Fluxo de Exceção: As credenciais podem ser inválidas e o sistema pode negar o acesso do usuário. CSU016Agendar Salas Sumário: Usuário agenda uma sala para utilização posterior. Ator primário: Usuário. Ator secundário: Banco de Dados. Pré-condição: Usuário está autenticado no sistema. Fluxo Principal: 1. O usuário identifica salas e horários. 2. O usuário seleciona um horário e sala disponíveis. 3. O usuário confirma o(s) agendamento(s). Fluxo Alternativo (1): O usuário pode utilizar a interface apenas para identificar as salas e horários disponíveis/agendadas. Fluxo Alternativo (2): O usuário pode exportar/importar agendamentos e realocá-los na agenda de salas. Fluxo de Exceção: Se o horário e sala selecionados estiverem ocupados o sistema emitirá um aviso sobre a impossibilidade de agendamento. CSU017Manipular Arquivos no Banco de Dados Sumário: O usuário pode manipular arquivos e diretórios no Banco de Dados. Ator primário: Usuário. Ator secundário: Banco de Dados. Pré-condição: Usuário está autenticado no sistema. Fluxo Principal: 1. O usuário seleciona o arquivo ou diretório. 2. O usuário seleciona a operação que deseja realizar com ele (excluir, copiar, mover, compartilhar). Fluxo de Exceção (1): Caso o usuário copie um arquivo e o limite de armazenamento do usuário for atingido, o sistema emitirá uma aviso sobre a impossibilidade de armazenar o arquivo. Fluxo de Exceção (2): Se o usuário tentar compartilhar um arquivo com um usuário inexistente, o sistema emitirá uma aviso sobre a impossibilidade de compartilhar o arquivo devido a inexistência do usuário selecionado. CSU018Carregar Arquivos para o Projetor Sumário: O temporizador define com base em agendamentos prévios realizados pelo usuário quando carregar o arquivo para o projetor. Ator primário: Temporizador. Atores secundários: Projetor, Banco de Dados e Usuário. Pré-condição: Agendamento prévio realizado pelo usuário. Fluxo Principal: 1. O temporizador verifica que há um arquivo a ser carregado para um projetor. 2. O temporizador carrega o arquivo do banco de dados para o projetor. |
Modelo de Domínio
Arquivo: Diagrama no Astah.
Desenvolvimento
Plano de Desenvolvimento
A execução do projeto, dentro da disciplina de Projeto Integrador II de 2015.1, consistirá de 2 ciclos de desenvolvimentos. Ao final de cada ciclo, os conjuntos de requisitos funcionais abaixo devem ser satisfeitos:
Ciclo 1 |
---|
|
Ciclo 2 |
---|
|
Ciclos Posteriores / Implementações adicionais |
---|
|
Estudo das Tecnologias
Sincronização de Diretórios Utilizando Rsync
Sincronização de Diretórios Utilizando Rsync [1] - Solução Obsoleta |
---|
1. Primeiramente no servidor e no cliente tem que estar instalado a ferramenta rsync. Caso não esteja:$ sudo apt-get install rsync
2. Também no servidor deve estar instalado o servidor ssh $ sudo apt-get install openssh-server
3. Crie o arquivo /etc/rsyncd.conf configuração para rsync.
# /etc/rsyncd: configuration file for rsync daemon mode
# configuration:
# limitar o acesso aonde os usuários podem enviar arquivos
use chroot = yes
# número máximo de conexões
max connections = 2
# hosts (ips) que podem ser conectar ao servidor rsync
hosts allow = 192.168.1.0/255.255.255.0
timeout = 600
# ignorar arquivos que não podem ser lidos
ignore nonreadable = yes
# usuários que podem operações de send e recv.
auth users = karol
# arquivo com os usuários e senhas
secrets file = /etc/rsyncd.secrets
# não há nenhuma restrição para manipular os arquivos e pastas
uid = root
gid = root
dont compress = *
# ativar o log de send e recv
transfer logging = yes
# formato do arquivo de log de transferência
log format = %t: host %h (%a) %o %f %L (%l bytes). Total %b bytes.
log file = /etc/log/rsyncd.log
# pastas que não serão mostradas ao adim e usuários do servidor
exclude = lost+found/
#pid file = /var/run/rsyncd.pid
[backup]
path = /home/karol/raiz
read only = no
comment = diretório do projetor
4. Criar /etc/rsyncd.secrets para a senha do usuário. Usuário deve ser o mesmo que o anterior, com a senha usada para fazer login na máquina remota como o usuário indicado. $ Sudo gedit /etc/rsyncd.secrets
user: password
# /etc/rsync.secrets
# Usuários e senhas que se conectarão ao servidor
# Formato:
# <usuario>:<senha>
karol:karol0802
5. Criar /etc/rsyncd.log onde esse irá gravar: %t: o tempo que foi feito o download.
%h: o nome do host.
%a: o ip do servidor remoto.
%o: qual foi a operação que o cliente realizou (send, receive, delete).
%f: nome do arquivo.
%L: qual será o symlink => hardlink.
%l: tamanho do arquivo em bytes.
%b: número de bytes realmente transmitidos.
6. Transferindo arquivos com rsync:
$ rsync -LCravzp /path_origem/ user@hostname:/path_destino/
$ rsync -LCravzp /home/karol/backup/ karol@192.168.1.7:/home/karol/raiz/equipamentos/projetor/projetor1/
$ rsync -LCravzp /path_destino/ user@hostname:/path_origem/
$ rsync -LCravzp /home/karol/raiz/equipamentos/projetor/projetor1/ karol@192.168.1.7:/home/karol/backup/
-L: transforma link simbólico de origem em um hard link no destino.
-C: auto-ignora arquivos idênticos.
-r: recursividade, faz ele buscar arquivos nas subpastas.
-a: indica que estarão sendo copiados arquivos.
-v: modo verboso, mais informações da cópia.
-z: comprime os arquivos durante a cópia.
-p: indicador de progresso de cópia
7. Para criar um link simbólico da pasta do usuário para um projetor deve executar o seguinte comando. $ ln -s /path_origem/arquivo /path_destino/ nome_do_link_simbolico
$ ln -s /home/karol/raiz/usuarios/ana/redes/lista.pdf /home/karol/raiz/equipamentos/projetor/projetor1/sb_lista.pdf
|
Sincronização de Diretórios Utilizando Rsync [2] - Solução Atual | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Exibição de PDF com xpdf em Virtual Display
Exibição de PDF com xpdf em Virtual Display [1] - Solução obsoleta, substituída por [2] | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Como parte do Detalhamento da Especificação referente ao Ciclo 1 de desenvolvimento foi estudada a projeção de processos que utilizem interface gráfica em um virtual display, com ênfase na exibição de arquivos PDF através do visualizador xpdf e envio de comandos para o mesmo através de outro terminal. Procedimentos realizados com uma instalação normal do Ubuntu 64bits (versões Gnome e padrão 12.04 e 14.04), e com a instalação dos pacotes referentes ao xpdf.
|
Exibição de PDF com xpdf em Virtual Display [2] - Solução obsoleta, substituída por [3] | ||||
---|---|---|---|---|
Como parte do Detalhamento da Especificação referente ao Ciclo 1 de desenvolvimento foi estudada a projeção de processos que utilizem interface gráfica em um virtual display, com ênfase na exibição de arquivos PDF através do visualizador xpdf e envio de comandos através de um terminal para uma sessão remota da aplicação. Procedimentos realizados com uma instalação normal do Ubuntu 64bits (versões Gnome e padrão 12.04 e 14.04), e com a instalação dos pacotes referentes ao xpdf. Os procedimentos também foram testados em uma placa Raspberry Pi B+, utilizando a distribuição Minibian e instalando os pacotes referentes ao Xorg e xpdf.
|
Exibição de PDF com xpdf em Virtual Display [3] - Solução obsoleta, substituida pelo Web Service | ||||||
---|---|---|---|---|---|---|
Como parte do Detalhamento da Especificação referente ao Ciclo 1 de desenvolvimento foi estudada a projeção de processos que utilizem interface gráfica em um virtual display, com ênfase na exibição de arquivos PDF através do visualizador xpdf e envio de comandos através de um terminal para uma sessão remota da aplicação. Procedimentos realizados com uma instalação normal do Ubuntu 64bits (versões Gnome e padrão 12.04 e 14.04), e com a instalação dos pacotes referentes ao xpdf. Os procedimentos também foram testados em uma placa Raspberry Pi B+, utilizando a distribuição Minibian e instalando os pacotes referentes ao Xorg e xpdf.
|
Estudo da Raspberry Pi B+
Auto Login |
---|
Para realizar login automático basta editar o arquivo inittab em etc: $ vim /etc/inittab
Comente a linha: # 1:2345:respawn:/sbin/getty 115200 tty1
E insira logo abaixo da mesma: 1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1
Onde pi é o nome do usuário que deseja iniciar a sessão automaticamente.
|
Expansão do sistema de arquivos no SD |
---|
Algumas distribuições raspberry não utilizam completamente o espaço de armazenamento do cartão SD, havendo um espaço livre que pode ser "anexado" ao sistema de arquivos da distribuição. Para realizar a expansão há diversos procedimentos, mas a que destaca-se pela facilidade é a instalação do raspi-config, que possui comandos para configuração/personalização do sistema. Para a instalação da aplicação em um sistema derivado do Debian (como o Minibian), basta executar o seguinte comando: $ apt-get install raspi-config
A ferramenta oferece opções de configuração referentes a idioma, interface do teclado, expansão do sistema de arquivos, gerenciamento da frequência do clock, entre outros. Para expandir o sistema de arquivos basta apenas selecionar a opção Expand Filesystem e confirmar a operação.
O sistema também pode ser redimensionado utilizando um editor de partições, como o gparted |
Instalação do Xorg |
---|
Para a instalação do Xorg basta executar o comando abaixo: $ apt-get install xorg
|
Instalação do xpdf |
---|
Para a instalação do xpdf basta executar o comando abaixo: $ apt-get install xpdf
|
Instalação do rsync |
---|
Para a instalação do Rsync basta executar o comando abaixo: $ apt-get install rsync
|
Instalação do openssh-server |
---|
Para a instalação do openssh-server basta executar o comando abaixo: $ apt-get install openssh-server
|
Instalação do python 2.7 |
---|
Para instalação do python 2.7 basta executar o comando abaixo: $ apt-get install python
|
Instalação do python pip |
---|
Para instalação do python pib basta executar o comando abaixo: $ apt-get install python-pip
|
Instalação do crontab |
---|
O Crontab já está presente na distribuição utilizada (minibian), mas caso seja necessário instalar em algum sistema: $ apt-get install cron
|
Criação de usuário |
---|
Para criar um usuário basta executar o comando: $ adduser user
Onde user refere-se ao nome de usuário que deseja-se criar.
|
Utilizar internet na raspberry através de rede via Ubuntu |
---|
|
API's de implementação
API Web-Service a ser implementado na Raspberry Pi B+
API Web-Service a ser implementado na Raspberry Pi B+ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
API Web-Service a ser implementado no GUI
API Web-Service a ser implementado no GUI | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Implementação do Web Service na Raspberry
Instalação dos componentes necessários |
---|
1. XpdfVisualizador de PDF's. $ sudo apt-get install xpdf
2. PythonLinguagem de programação utilizada na implementação do web service. $ sudo apt-get install python
3. Python-pipGerenciador de extensões python. $ sudo apt-get install python-pip
4. Python-devPacote python para desenvolvedores. $ sudo apt-get install python-dev
5. Framework FlaskFramework utilizado na implementação de web services. $ sudo pip install flask
6. Extensão HTTPAuth do FlaskPara autenticação via HTTP. $ sudo pip install flask-httpauth
7. Extensão netifaces para PythonFornece informações sobre as interfaces de conexão. $ wget https://pypi.python.org/packages/source/n/netifaces/netifaces-0.10.4.tar.gz
$ tar xvzf netifaces-0.10.4.tar.gz
$ cd netifaces-0.10.4
$ python setup.py install
8. Extensão Cors do FlaskDevido a política de mesma origem (same origin policy), configurada como padrão nos servidores, qualquer requisição feita de diferentes domínios é bloqueada pelos navegadores, isto impede que ataques de Cross-domain sejam feitos. A habilitação da extensão CORS (cross-origin resource sharing) cria um caminho para que estas requisições sejam feitas de uma maneira mais segura, sem que todas as requisições deste tipo sejam habilitadas. Para habilitar os CORS é necessário primeiramente instalar a biblioteca para o suporte do CORS no servidor.
|
Implementação do Web Service |
---|
#!/usr/bin/python
__author__ = "Matuzalem - Projeto Integrador II - Engenharia de Telecomunicacoes - Junho de 2015"
__date__ = "$11/06/2015 01:09:22$"
import sys
import netifaces # para capturar a interface do servidor automaticamente, caso insira manualmente o ip do servidor e descartavel, desde que comente as linhas de codigo equivalentes
from flask import Flask, jsonify
from flask import abort
from flask import make_response
from flask import request
from flask import url_for
from flask import send_file # enviar arquivos thumbs pela rede
from flask.ext.httpauth import HTTPBasicAuth
from flask.ext.cors import CORS # habilita troca de informacoes cross domain
auth = HTTPBasicAuth()
import subprocess
import os
app = Flask(__name__)
cors = CORS(app)
# Este servidor foi desenvolvido considerando a estrutura /root/User para o armazenamento de pdfs na raspberry
#####################[DEVE SER PREENCHIDO]############################
usuario = 'User' # usuario conectado a raspberry
interface='lo' # interface em que o servidor funcionara, para obter o ip automaticamente
porta=5000 # porta em que o servidor ouvira
######################################################################
caminho = "" # diretorio onde esta localizado o diretorio do usuario
pastaUsuario = "" # diretorio usuario
numeroPaginas="" # numero de paginas do arquivo
paginaAtual="" # pagina atual do arquivo
### Como listar arquivos em diretorio e seus subdiretorios ###
# curl -i http://localhost:5000/projetar
# Lista os arquivos do tipo pdf em /root/{usuario}/ e o numero de paginas de cada arquivo
@app.route('/projetar', methods=['GET'])
def obtem_arquivos():
lista = []
#https://docs.python.org/2/library/os.html
for root, dirs, files in os.walk(caminho+usuario+'/'):
for nome in files:
if nome.endswith(".pdf"):
path = os.path.join(root, nome)
size = os.stat(path).st_size # in bytes
linha = {}
linha['numeroPaginas'] = subprocess.check_output("/usr/bin/pdfinfo "+path+" | grep -oP '(?<=Pages: )[ A-Za-z0-9]*'", shell=True)[:-1] # [:-1] remove o ultimo elemento do vetor, no caso \n
linha['nome'] = nome
lista.append(linha)
return jsonify({'arquivos': lista}), 200
############################ Auxiliares ##############################
# verifica se um arquivo existe em um determinado diretorio
def verifica_existencia(diretorio, arquivo):
if (os.path.exists(diretorio+arquivo) == True):
return True
else:
return False
######################### Metodos do XPDF ############################
# curl -i http://localhost:5000/projetar/{arquivo.pdf}
# Abre um pdf
@app.route('/projetar/<arquivo>', methods=['GET'])
def abre_pdf(arquivo):
# Chamada de processo nao bloqueante - fica em background
local = pastaUsuario+arquivo
if (verifica_existencia(pastaUsuario,arquivo) == True):
p1 = os.spawnlp(os.P_NOWAIT,"xpdf","/usr/bin/xpdf","-fullscreen","-remote", arquivo, local)
# /usr/bin/pdfinfo /root/User/arquivo.pdf | grep -oP '(?<=Pages: )[ A-Za-z0-9]*'
# verifica o numero de paginas do pdf
global numeroPaginas
global paginaAtual
numeroPaginas = subprocess.check_output("/usr/bin/pdfinfo "+local+" | grep -oP '(?<=Pages: )[ A-Za-z0-9]*'", shell=True)
paginaAtual = 1
return jsonify({'resultado': True}), 200
else:
print 'Usuario '+usuario+' tentou acessar o arquivo '+arquivo+' inexistente!'
return jsonify({'resultado': False}), 404
# curl -i http://localhost:5000/projetar/{arquivo.pdf}/avancarProjecao
# Avanca uma pagina
@app.route('/projetar/<arquivo>/avancarProjecao', methods=['GET'])
def avanca_pagina(arquivo):
comando = 'nextPage'
global paginaAtual
if(int(paginaAtual) < int(numeroPaginas)):
# chamada de processo bloqueante, porem o xpdf termina logo apos a execucao
paginaAtual = paginaAtual + 1
p = subprocess.call(['xpdf.real','-remote',arquivo,'-exec', comando])
return jsonify({'resultado': True}), 200
else:
print 'Usuario '+usuario+' tentou acessar a pagina '+str(paginaAtual+1)+' do pdf '+pastaUsuario+arquivo+' inexistente!'
return jsonify({'resultado': False}), 404
# curl -i http://localhost:5000/projetar/{arquivo.pdf}/retrocederProjecao
# Retrocede uma pagina
@app.route('/projetar/<arquivo>/retrocederProjecao', methods=['GET'])
def retrocede_pagina(arquivo):
if(int(paginaAtual) > 1):
comando = 'prevPage'
# chamada de processo bloqueante, porem o xpdf termina logo apos a execucao
subprocess.call(['xpdf.real','-remote',arquivo,'-exec', comando])
return jsonify({'resultado': True}), 200
else:
print 'Usuario '+usuario+' tentou acessar a pagina '+str(paginaAtual-1)+' do pdf '+pastaUsuario+arquivo+' inexistente!'
return jsonify({'resultado': False}), 404
# curl -i http://localhost:5000/projetar/{arquivo.pdf}/saltarProjecao/{numPagina}
# Avanca para uma pagina do pdf, se a pagina nao existir retorna um codigo de erro
@app.route('/projetar/<arquivo>/saltarProjecao/<int:pagina>', methods=['GET'])
def salta_paginas(arquivo,pagina):
global paginaAtual
if(pagina <= int(numeroPaginas) and (int(pagina) > 0)):
comando = 'gotoPage('+str(pagina)+')'
# chamada de processo bloqueante, porem o xpdf termina logo apos a execucao
subprocess.call(['xpdf.real','-remote',arquivo,'-exec',comando])
paginaAtual = pagina
return jsonify({'resultado': True}), 200
else:
print 'Usuario '+usuario+' tentou acessar a pagina '+str(pagina)+' do pdf '+pastaUsuario+arquivo+' inexistente!'
return jsonify({'resultado': False}), 404
# curl -i http://localhost:5000/projetar/{arquivo.pdf}/fechar
# Fechar projecao
@app.route('/projetar/<arquivo>/fechar', methods=['GET'])
def fechar_projecao(arquivo):
comando = 'quit'
global paginaAtual
global numeroPaginas
paginaAtual = numeroPaginas = ""
# chamada de processo bloqueante, porem o xpdf termina logo apos a execucao
subprocess.call(['xpdf.real','-remote',arquivo,'-exec', comando])
return jsonify({'resultado': True}), 200
###################### OBTEM THUMB ##########################
# curl -i http://localhost:5000/projetar/{arquivo.pdf}/obterThumb/{thumb}
# Retorna um thumb do tipo jpg identificado por {arquivo}-{thumb}.jpg
@app.route('/projetar/<arquivo>/obterThumb/<int:thumb>', methods=['GET'])
def obter_thumb(arquivo, thumb):
if((thumb < int(numeroPaginas)) & (thumb >= 0)):
fileName, fileExtension = os.path.splitext(arquivo)
caminhoArquivo = pastaUsuario+'thumbs/'+fileName+'-'+(str(thumb))+'.jpg'
return send_file(caminhoArquivo, mimetype='image/jpg')
else:
caminhoArquivo = pastaUsuario+'thumbs/'+'erro.jpg'
return send_file(caminhoArquivo, mimetype='image/jpg')
###########COMANDOS DE CONTROLE DE PROJECAO##################
############OS COMANDOS NAO ESTAO FUNCIONAIS##########################
# curl -i http://localhost:5000/projetar/ligarProjetor
# Retrocede uma pagina
#@app.route('/projetar/ligarProjetor, methods=['GET'])
#def liga_projetor():
# subprocess.call(['echo "standby 0" | cec-client -s'])
# return jsonify({'resultado': True}), 200
# curl -i http://localhost:5000/projetar/desligarProjetor
# Retrocede uma pagina
#@app.route('/projetar/desligarProjetor, methods=['GET'])
#def desliga_projetor():
# subprocess.call(['echo "on 0" | cec-client -s'])
# return jsonify({'resultado': True}), 200
###############################################################
@app.errorhandler(404) ## Tratamento de erro
def not_found(error):
return make_response(jsonify({'Erro': 'Recurso nao encontrado!'}), 404)
##############################################################
if __name__ == "__main__":
print "Servidor no ar!"
caminho = os.path.expanduser('~')+'/' # obtem o diretorio do usuario do SO
pastaUsuario = caminho+usuario+'/' # obtem o diretorio do usuario conectado (User)
ip = netifaces.ifaddresses(interface)[2][0]['addr'] # obtem o ip referente a interface
app.run(debug=True,host=ip,port=porta)
python servidor.py
|
Resultados obtidos na implementação do projeto
Nessa etapa final, cada integrante do grupo ficou responsável por uma parte do projeto. Sendo que as partes individuais da maioria funcionaram, mas tivemos alguns problemas na parte da integração. relataremos abaixo as partes do trabalho que funcionaram e as que tivemos problemas.
- Obtivemos sucesso na parte de manipulação dos slides colocados na raspberry, nessa parte conseguíamos via uma aplicação no celular, avançar ou retroceder nos slides. Só tínhamos uma pequena demora na passagem, pelo fato da demora no processamento das imagens.
- As partes das aplicações visualizadas pelo usuário, no website, funcionaram em partes:
- Conseguimos fazer a autenticação dos usuários, porém não foi possível manter a conexão do usuário
- A parte do Upload dos arquivos funcionou perfeitamente, porém como não conseguimos manter a conexão, tivemos que criar um usuário fictício, para assim colocarmos os arquivos na pasta desse usuário, só ressaltamos que não foi implementado a exclusão de arquivos, isso foi deixado para o ciclo 2, que seria para o projeto de ideias inovadoras
- O agendamento dos arquivos foi feito a parte que estava descrita para ser realizada no ciclo 1 do projeto, mas também tivemos o mesmo problema com o usuário, descrito anteriormente
- Tivemos um pequeno problema na hora que fomos tentar realizar o rsync com a raspberry, com isso alteramos o script para relializar a sincronização dos dados. Não foi possível testar a integração completa do sistema Webba devido a problemas técnicos ocorrido no momento. Porém, este mesmo projeto foi inscrito no projeto Ideias Inovadoras do IFSC, caso consiga passar para a etapa de desenvolvimento do projeto a meta da equipe será implementar todos os requisitos propostos previamente para o projeto e torná-lo um produto.