sábado, 13 de fevereiro de 2016

Solução caseira para segurança doméstica

As soluções de segurança que tenho visto são caras, então resolvi desenvolver uma solução caseira. Decidi que com um Raspberry Pi, uma câmera barata e um pouco de código, poderia fazer algo tão bom quanto sistemas dez vezes mais caros.

O mais importante é que o sistema deveria enviar notificações para o celular. O Whatsapp não permite robôs, então recorri ao Telegram.

Desenvolvi usando um Raspberry Pi B, mas o sistema final roda num Raspberry Pi A+ (que é ainda menor e mais barato). Acredito que funcionaria igualmente bem num Raspberry Pi Zero (que custa apenas US$5).

A ideia do projeto é bastante simples: a câmera, quando ativada por movimento, copia imagens para o Raspberry Pi e este, por sua vez, as encaminha para uma conta do Telegram. O Telegram entrega as fotos para o meu celular.

Se o código da câmera fosse aberto, ou ela oferecesse alguma API, seria possível que ela falasse diretamente com o Telegram. Ponto negativo para o código fechado.

Ingredientes
  • Um Raspberry Pi B (512MB de RAM, 700MHz de CPU e custa ~US$25);
  • Uma câmera D-Link 930LB (custa menos de R$200,00);
  • Uma conta no Telegram (Whatsapp não aceita robôs);
  • Um cartão de memória SDHC de 16GB (um de 8GB já resolveria);
  • Um pouco de Perl.
Passos

1. Gravar Raspbian no cartão.

2. Instalar um servidor de ftp (sudo apt-get install vsftpd).

3. Configurar o servidor de ftp (/etc/vsftpd.conf).

É preciso habilitar a possibilidade de escrever e de fazer login com contas locais:


local_enable=YES
write_enable=YES


4. Configurar um ramdisk (para não desgastar o cartão de memória, se o número de escritas fugir ao controle e porque é mais rápido).

É preciso adicionar esta linha ao arquivo /etc/fstab:


tmpfs  /home/pi/tmp  tmpfs  nodev,nosuid,size=1M 0 0


Esse comando cria um espaço de 1MB que fica montado no diretório tmp/ dentro do home do usuário pi, mas poderia ser qualquer outro lugar. Os arquivos não passam de 50KB, então essa área poderia ser muito menor.

5. Configurar a câmera.

Configurei a câmera para fazer o ftp da imagem quando for detectado um movimento (usei sensibilidade de 30%, porque ela envia muitas imagens com mais que isso).

O nome do arquivo indiquei como DCS-930LB e isso acaba resultando num arquivo JPEG chamado DCS-930LB.jpg.

6. Criar uma conta no Telegram.

É preciso procurar a conta @BotFather e conversar. Ele dá todas as instruções.

7. Programar em Perl (essa é a melhor parte).

É preciso instalar algumas bibliotecas, o curl, o cpanm e o módulo WWW::Telegram::BotAPI:

sudo apt-get install libnet-ssleay-perl libio-socket-ssl-perl --fix-missing
sudo apt-get install curl
sudo curl -L http://cpanmin.us | perl - --sudo App::cpanminus
sudo cpanm WWW::Telegram::BotAPI

Usei um modelo de robô e fiz algumas adaptações.

Em primeiro lugar, criei ums lista das contas autorizadas (para que estranhos não brinquem com meu robô):


my %chat_ids=(
  123456789=>'forinti',
  987654321=>'derpina'
);


Depois, mudei o loop principal para descansar 5s a cada iteração, verificar se a imagem mudou (pela hora de criação), e enviar a imagem se algo novo surgiu.


my $paused=0;
my $last_update=get_last_update();
while(1) {
  sleep(5);
  my $update=get_last_update();
  if(!$paused && $update>$last_update) {
    for my $id (keys %chat_ids) {
      $api->sendPhoto({
         chat_id=>$id, 
         photo=>{file=>'/home/pi/tmp/DCS-930LB.jpg'}
      });
    } 
    $last_update=$update;
  }
  ...


Finalmente, criei comandos para recuperar a última imagem (/li), parar o envio (/pause) e reiniciar o envio (/go).

sub get_last_update {
  return (stat('/home/pi/tmp/DCS-930LB.jpg'))[9];
}

sub get_last_image {
  return {
    method=>'sendPhoto',
    photo=>{ file=> '/home/pi/tmp/DCS-930LB.jpg' }
  };
}

sub pause {
  $paused=1;
  return 'Parou. Por enquanto...';
}

sub go {
  $paused=0;
  return 'Reiniciou.';
}


Resultado

Consegui produzir um sistema de segurança bastante simples e barato. Ele consome pouquíssima energia (menos de R$10,00 para operar um ano inteiro) e não precisa ser monitorado já que envia alertas. Por usar pouca energia, poderia funcionar ligado a uma bateria ou a um painel solar. Se conectasse a uma rede de celular, seria realmente resiliente.