Campainha IoT com Raspberry Pi Zero W 24

Com a popularização e redução de preço de placas de desenvolvimento que são verdadeiros computadores – como a Raspberry Pi Zero W por exemplo – um mundo de novos projetos ficou disponível a qualquer um que queira aprender e esteja disposto a botar a mão na massa. Isso refletiu em muitos projetos aplicados ao dia-a-dia. Um deles é o que será tratado aqui neste post: uma campainha IoT com Raspberry Pi. Com ela, você poderá saber quem tocou sua campainha (através de uma foto) e quando isso ocorreu, de qualquer lugar do mundo com conexão à Internet!

Campainha IoT

Material necessário para a campainha IoT

Para fazer este projeto, você precisará de:

* Assume-se neste post que a Raspberry Pi Zero W já contenha o Raspbian instalado e configurado (ou seja, a Raspberry Pi Zero W deve estar operacional).

Overview do projeto

O projeto funcionará da seguinte maneira: ao ser pressionado um botão / interruptor, uma foto da pessoa que o apertou será tirada pela Raspberry Pi Zero W (usando a câmera Raspberry Pi) e enviada, juntamente com a data e horário do evento ocorrido, ao morador da casa através do Pushbullet. O Pushbullet, por sua vez, envia uma notificação push ao celular do morador, tornando possível que este saiba (em qualquer lugar do mundo, a qualquer hora) quem tocou a campainha de sua casa.

Preparação – câmera Raspberry Pi

Antes de prosseguir com o projeto, é preciso preparar a Raspberry Pi para se comunicar com a câmera. Para isso, siga este nosso tutorial.

Pushbullet – o que é e como utilizar?

O Pushbullet é um app + serviço online que permite que qualquer tablet e smartphone (e também qualquer computador, através do site oficial) receba mensagens (incluindo notificações push) sem custo algum. Trata-se de uma das formas mais simples e eficientes de se enviar notificações a smartphones a partir de dispositivos diversos.
O Pushbullet direciona as mensagens aos destinatários corretos (todos os seus dispositivos cadastrados) através de uma chave. Esta chave é um código único associado a sua conta Pushbullet, sendo esta chamada de Access Token.

Figura 1 - logo do Pushbullet

Para utilizar o Pushbullet, é preciso instalar o aplicativo oficial do Pushbullet no smartphone para receber as notificações e, além disso, é preciso obter o Access Token.  Portanto, se algo (este projeto, por exemplo) enviar notificação pelo Pushbullet com o dado Access Token correspondente ao da sua conta, todos os seus dispositivos com o aplicativo a receberão. Para gerar o Access Token, siga o procedimento abaixo:

  1. Instale o aplicativo oficial do Pushbullet nos dispositivos que devem receber notificações do projeto e faça o cadastro. Se desejar, é possível também fazer o cadastro através de redes sociais (como Facebook, por exemplo);
  2. De seu computador, acesse o site oficial do Pushbullet;
  3. Faça o login com as mesmas credenciais utilizadas no cadastro;
  4. Feito o login, clique em “Settings”, depois em “Account” e, por fim, em “Create Access Token”, destacado na figura abaixo.
  5. Ao clicar, o site exibirá sua Access Token.
    Atenção: anote / salve em local seguro, pois você não vai visualizar o Acess Token novamente (se você o perder, terá que criar outro seguindo este mesmo procedimento).

Circuito esquemático do projeto

O circuito esquemático do projeto da campainha IoT pode ser visto na figura abaixo:

 

Código-fonte

O código-fonte do projeto pode ser visto abaixo:

#Projeto: smart doorbell
#Autores: Pedro Bertoleti e MakerHero
#Data: Outubro/2017
from datetime import datetime
import time
import os
import RPi.GPIO as GPIO
import sys
import requests
import json

#Definicao do Access Token (Pushbullet)
ACCESS_TOKEN = 'tttttttttttttttttttttttttttttttttt'   #substituir "tttttttttttttttttttttttttttttttttt" pelo seu Acces Token

#Definicao do GPIO do interruptor
GPIO_Interruptor = 12  #pino 12 do header de GPIO da Raspberry Pi Zero W

#Funcao: configura GPIO do interruptor 
#Parametros: nenhum
#Saida: nenhum
def ConfiguraGPIOInterruptor():
	# inicia a biblioteca RPi.GPIO usando numeracao do Header
	print("configurando GPIO")
	GPIO.setwarnings(False)
	GPIO.setmode(GPIO.BOARD)
	GPIO.setup(GPIO_Interruptor, GPIO.IN, pull_up_down = GPIO.PUD_UP)
	print("GPIO ok return")
	return

#Funcao: verifica se o interruptor foi acionado
#Parametros: nenhum
#Saida: 1: interruptor foi acionado
#       0: interruptor nao foi acionado
def VerificaAcionamentoInterruptor():
	
	if (GPIO.input(GPIO_Interruptor) == GPIO.LOW):
		print("botao acionado")
		#um acionamento foi detectado. Faz o debounce (tempo = 20ms)
		time.sleep(0.020)
		if (GPIO.input(GPIO_Interruptor) == GPIO.LOW):
			#acionamento confirmado
			print("botao acionado")
			return 1
		else:
			#acionamento nao confirmado
			return 0
	else:
		#nenhum acionamento detectado
		return 0

#Funcao: bloqueia programa enquanto interruptor esta acionado
#Parametros: nenhum
#Saida: nenhum
def BloqueiaProgramaSeInterruptorAcionado():
	while(GPIO.input(GPIO_Interruptor) == GPIO.LOW):
		continue
	return
	
#Funcao: envia foto via Pushbullet
#Parametros: nenhum
#Saida: nenhum	
def EnviaFotoPorPushbullet():
	print("enviando foto push")
	global ACCESS_TOKEN
	
	#envia notificacao por escrito da data e hora do acionamento
	now = datetime.now()
	StringDataHora = str(now.hour)+":"+str(now.minute)+":"+str(now.second)+" em "+str(now.day)+"/"+str(now.month)+"/"+str(now.year) 
	StringMsg = "Acionamento da campainha em "+StringDataHora+". Foto abaixo:"
	data_send = {"type": "note", "title": "Notificacao - smart doorbell", "body": StringMsg}
	resp = requests.post('https://api.pushbullet.com/v2/pushes', data=json.dumps(data_send), headers={'Authorization': 'Bearer ' + ACCESS_TOKEN, 'Content-Type': 'application/json'})
 
	#envia arquivo de foto:
	ArquivoFoto = "/home/pi/FotoSmartDoorbell.jpg"
	jpgbase = os.path.basename(ArquivoFoto)
 
	res = requests.post("https://api.pushbullet.com/v2/upload-request",
						headers={
							"Access-Token": ACCESS_TOKEN,
							"Content-Type": "application/json"
                    },
                    data=json.dumps({"file_name": jpgbase, "file_type": "image/jpeg"}))
 
	js = json.loads(res.content)
	files = {'file': open(jpgbase, 'rb')}
	requests.post(js['upload_url'], files=files)
	fileurl = js['file_url']
	res = requests.post("https://api.pushbullet.com/v2/pushes",
						headers={
							"Access-Token": ACCESS_TOKEN,
							"Content-Type": "application/json"},
						data=json.dumps({
							"email": "[email protected]",
							"type": "file",
							"file_name": jpgbase,
							"file_type": "image/jpg",
							"file_url": fileurl}))
	
	return
		
#--------------------------------
#       Programa principal
#--------------------------------
#delay para aguardar sistema operacional iniciar por completo (necessario caso esta aplicacao rodar em background)
#time.sleep(30)
ConfiguraGPIOInterruptor()

while True:
	try:
		if (VerificaAcionamentoInterruptor()):
			#houve acionamento do botao. Tira a foto e a envia via Pushbullet
			print("tirando foto")
			os.system("raspistill -o /home/pi/FotoSmartDoorbell.jpg")
			print("foto tirada")
			EnviaFotoPorPushbullet()
			
			#para evitar mais de um envio por acionamento de interruptor, aqui o 
			#programa e bloqueado se o interruptor ainda estiver acionado
			BloqueiaProgramaSeInterruptorAcionado()
			
	except (KeyboardInterrupt):
		print "A aplicacao foi encerrada."
		exit()

Projeto em ação!

Veja abaixo o projeto da Campainha IoT em ação:

Gostou do projeto Campainha IoT com Raspberry Pi Zero W? Então deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

24 Comentários

  1. Olá, gostaria de fazer o mesmo projeto, só que utilizando um ESP8266 ao invés do Raspberry Pi, e uma webcam, ou módulo de câmera OV7670 (ou similar)

    Acho interessante também enviar um trigger usando IFTTT para a Alexa me avisar que tem alguém no portão, e assim eu olhar o celular

    Não sou programador, dei a idéia e gostaria MUITO de executá-la

  2. Parabéns pelo projeto! É possível enviar um comando e destravar a porta?

    1. Carlos,

      Acredito que com os devidos ajustes no projeto é possível sim!

      Abraços!
      Diogo – Equipe MakerHero

  3. Excelente!
    Seria possível estabelecer uma conexão por voz com a pessoa, através do celular como se o morador estivesse dentro da casa?

    1. Carlos,

      Teoricamente sim, mas acredito ser meio complicadinho de botar para funcionar.

      Abraços!
      Diogo – Equipe MakerHero

  4. Gostaria de fazer um projeto semelhante l, mas sem a câmera, apenas o interruptor. Como ficaria o código?

    1. Italo,

      Você pode excluir a função que envia foto pelo pushbullet no código. Tanto a inicialização dela (Onde está escrito como ela funciona), quanto no fim do código, quando se chama ela 🙂 Em seguida, você deve fazer uma nova função com o que você deseja fazer ao apertar o botão.

      Abraços!
      Diogo – Equipe MakerHero

  5. Consigo fazer o projeto com qualquer versão da placa com o mesmo código fonte? Ou preciso de adequações na programação?

    1. Italo,

      Vai funcionar nas outras placas também 🙂

      Abraços!
      Diogo – Equipe MakerHero

  6. Bom dia,
    Parabéns pelo projeto, é excelente!
    É possível realizar esse projeto com um orange pi ?
    Eu receberia a imagem do meu celular mesmo se eu tivesse conectado a outra rede? Por ex. se eu não tivesse em casa e tivesse usando uma rede 3G no meu cel.
    Desde já agradeço.

    1. Bom dia. Muito obrigado!

      Seguem as respostas de suas perguntas:

      – É possível realizar esse projeto com um orange pi ?
      Sim,porém o projeto deveria ser modificado, uma vez que o acesso aos GPIOs na Orange PI não é feito com a mesma biblioteca. Além disso, não sei o quão complicado seria colocar uma camera tipo a Raspicam pra funcionar numa Orange PI (nunca tentei).
      – Eu receberia a imagem do meu celular mesmo se eu tivesse conectado a outra rede?
      Sim. todos os serviços que o projeto utilizam ficam em nuvem.

      Atenciosamente,
      Pedro Bertoleti

      1. Obrigado pelas resposta Pedro.
        Tenho mais uma dúvida: seria possível configurar mais de um celular para receber a imagem ao mesmo tempo?
        Obrigado

        1. SIm. Todos os dispositivos (celulares, tablets, computadores, etc.) com o app pushbullet instalado e que estiverem logados com a mesma conta daquela que publica irão receber.

  7. muito bom Pedro. estes projetos
    mas em particular eu tenho um que preciso muito. ele ja existe no mercado mas funciona com drive expecifico do motor.
    eu gostaria de saber se teriamos como fabrica ” um drive ” para fazer o motor funcionar
    este motor que eu uso é uma motor brushlles de 8 fios.

    voçe tem whatsapp . para podermos conversar, tenho uma empresa de equipamentos medicos e sao inumeras as ideias de inovaçoes para a area
    011 998842265

  8. Ola! Num seria legal uma campainha que registrasse a impressao digital do visitante ou alguma outra forma de identificar o visitante, solicitasse o nome do mesmo gravasse tudo numa midia(cartao de memoria ou outros) e na proxima visita quando o visitante clicasse no botao uma mensagem disparasse… “Bem vindo ‘visitante’!!!”…

    1. Olá Marcos!

      Seria interessante mesmo. Daria para fazer isso com RFID, tipo o que é feito nesse post:
      https://www.makerhero.com/blog/controle-acesso-leitor-rfid-arduino/

      O sensor de impressão digital acabou de chegar na nossa loja! Fizemos um post pra ele também:
      https://www.makerhero.com/blog/primeiros-passos-sensor-de-impressao-digital/

      Abraços!

      André – Equipe MakerHero

    2. Já viajando na maionese. Utilizar alguma api de reconhecimento facial e outra conversando com sua agenda de contatos… Quando enviar a imagem, aponta se essa pessoa é seu contato, se sim apresenta o na mesagem recebida e também da saudações como tu sugeres !

  9. Boa tarde

    A aplicação rodou quase que perfeitamente, ela envia a mensagem de texto, mas não a imagem.

    segue o erro:

    Traceback (most recent call last):
    File “/home/pi/Desktop/tcc.py”, line 115, in
    EnviaFotoPorPushbullet()
    File “/home/pi/Desktop/tcc.py”, line 84, in EnviaFotoPorPushbullet
    js = json.loads(res.content)
    File “/usr/lib/python3.4/json/__init__.py”, line 312, in loads
    s.__class__.__name__))
    TypeError: the JSON object must be str, not ‘bytes’

    Vocês poderiam me ajudar?

    1. Marcos, boa tarde.

      Você utilizou o mesmo código-fonte do post ou fez alguma modificação?

      1. A única mudança foi no código para tirar a foto, usei uma webcam e por isso usei o seguinte código.

        os.system(“sudo fswebcam /home/pi/FotoSmartDoorbell.jpg”)

        e setei o modo GPIO para BCM

        1. Marcos, duas considerações:

          – Você verificou se o arquivo da foto foi realmente criado?
          – Notei, pelo seu debug, que você utiliza Python 3 (3.4). Pelo que eu me recordo, no momento do desenvolvimento, eu estava utilizando o Python 2.7. Sendo assim, recomendo que faça o teste com a versão 2.7 do Python

          Atenciosamente,
          Pedro Bertoleti

          1. Bom dia Pedro,

            Já deu certo, o problema era que a função loads lê Strings, e o res.content era um byte.

            Eu criei uma variável foto = (res.content).encoded(“UTF-8”) e deu certo.

            Provavelmente o problema estava na versão do python msm.

            Obrigado pela atenção.

  10. Ótimo Projeto!

    Daria pra enviar um vídeo ao inves da imagem ?

    1. Diego, muito obrigado pela leitura e pelo elogio!

      Respondendo a sua pergunta: nunca fiz isso, mas ACHO que se você alterar o file type do JSON para o de video e gravar o video com alguma aplicação Linux (como a ffmpeg) você deve conseguir enviar vídeos sim.

      Sobre gravação de videos, este link pode ajudar: https://www.raspberrypi.org/forums/viewtopic.php?t=144223

      Atenciosamente,
      Pedro Bertoleti