Agendamento de tarefas no Linux com Raspberry Pi Zero W

Agendamento de tarefas no Linux com Raspberry Pi Zero W 2

A Raspberry Pi Zero W é uma placa de desenvolvimento de grande utilidade, podendo ser aplicada em robótica, vigilância remota, video-game portátil e, por último mas não menos importante, em automação. A automação de uma ação ou processo envolve, dentre outras etapas, a etapa de agendamento de eventos, algo de fundamental importância para a execução de atividades que requerem precisão e exatidão no tempo de início de execução (ativação/desativação de um irrigador automático, luz, eletrodoméstico, etc.). Neste post, será mostrado como fazer um agendamento (via Internet, com MQTT) de execução de uma tarefa na Raspberry Pi Zero W. No caso a tarefa executada será ligar um LED, o que pode ser facilmente substituído pelo acionamento de praticamente qualquer dispositivo/atuador (conforme você desejar). Assim você saberá como fazer o agendamento de tarefas no Linux.

Material necessário

Para fazer este projeto, você precisará de:

Pré-requisito:  hora da Raspberry Pi Zero W

Antes de mais nada, acerte a hora / fuso horário de sua Raspberry Pi Zero W. É fundamental que a hora da Raspberry Pi Zero W esteja correta / fuso-horário selecionado corretamente para que o agendamento de tarefas no Linux possa funcionar conforme o esperado.

Circuito esquemático

O circuito esquemático do projeto pode ser visto na figura 1.

Circuito Esquemático
Figura 1 – circuito esquemático

 

Instalação da biblioteca Paho-MQTT

Antes de prosseguir com o projeto, é necessário instalar a biblioteca PAHO-MQTT para Python. Para isso, execute o comando abaixo:

sudo pip install paho-mqtt

A instalação leva apenas alguns segundos, dependendo da velocidade de sua conexão à Internet.

Funcionamento do projeto

O funcionamento do projeto, do lado da Raspberry Pi Zero W, é dado pela atuação de dois scripts Python, executados em background:

  • alarme.py:Script Python responsável por automaticamente se conectar ao Broker MQTT quando a placa liga (e quando também possui conectividade à Internet). Uma vez em conectado ao broker, este script é responsável por receber via MQTT a hora de agendamento do evento e salvá-la em um arquivo texto (no caso, o arquivo alarme.txt, localizado no diretório /tmp). É necessário que a hora de agendamento do evento seja recebida via MQTT no formato “HH MM” (exemplo: 17 31)
    Este script roda de forma ininterrupta, ou seja, ele ficará ativo enquanto a Raspberry Pi Zero W estiver ligada.
  • verifica_evento_alarme.py:Script Python que é rodado a cada minuto, verificando se é o momento de disparar o evento agendado. Esse script é executado em background (na periodicidade informada, ou seja, de minuto em minuto) pelo scheduler de tarefas cron, nativo na distribuição Raspbian.
    No caso deste projeto, o evento a ser disparado é acender o LED durante todo o minuto agendado e, ao fim deste, apagar o LED.

Em suma, o script Python alarme.py é responsável por registrar o agendamento de tarefas no Linux enviado pela Internet (via MQTT) e o script verifica_evento_alarme.py, executado pelo cron, verifica de minuto em minuto se o LED deve ser aceso (caso a hora agendada corresponder à hora atual) ou apagado (caso a hora agendada não corresponder à hora atual). Para mais detalhes, veja o diagrama da figura 2.

Diagrama funcionamento do projeto
Figura 2 – diagrama de funcionamento do projeto

 

Criação e inicialização automática do alarme.py

Para criar o script alarme.py e fazer com que sua execução seja automaticamente realizada no inicialização da Raspberry Pi Zero W, siga os procedimentos abaixo:

  1. No diretório home, crie o arquivo alarme. py. Para isso, execute os comandos abaixo:
    cd ~
    nano alarme.py
  2. No editor de texto nano, cole o código abaixo. Não se esqueça de substituir o nome do tópico de subscribe (para quem você não interfira e não sofra interferÊncia do agendamento de outra pessoa).
    import paho.mqtt.client as mqtt
     import sysimport os#definicoes: 
     Broker = "iot.eclipse.org"
     PortaBroker = 1883
     KeepAliveBroker = 60
     TopicoSubscribe = "MQTTFilipeFlopAlarme" #dica: troque o nome do topico por algo "unico",                          
                                              #Dessa maneira, ninguem ira saber seu topico de
                                              #subscribe e interferir em seus testes#Callback - conexao ao broker realizada
     def on_connect(client, userdata, flags, rc):    
         #faz subscribe automatico no topico    
         client.subscribe(TopicoSubscribe)#Callback - mensagem recebida do broker
     def on_message(client, userdata, msg): 
         MensagemRecebida = str(msg.payload) 
         print("[MSG RECEBIDA] Topico: "+msg.topic+" / Mensagem: "+MensagemRecebida)     
         comando_escrita_horario = "echo "+MensagemRecebida+" > /tmp/alarme.txt"
         os.system(comando_escrita_horario)#programa principal
     #aguarda haver conectividade com a Internet
     while True:    
         resultado_ping = os.system("ping -c 1 8.8.8.8")    
         if (resultado_ping == 0):      
             breakclient = mqtt.Client()
     client.on_connect = on_connect
     client.on_message = on_message
     client.connect(Broker, PortaBroker, KeepAliveBroker)
     client.loop_forever()
  3. Aperte Ctrl + X e Ctrl + Y para sair e salvar
  4. Agora, crie um shell script chamado alarme.sh. Para isso, utilize o comando abaixo:
    nano alarme.sh
  5. No editor de texto nano, cole o código abaixo:
    #!/bin/bash
    /usr/bin/python /home/pi/alarme.py
  6. Aperte Ctrl + X e Ctrl + Y para sair e salvar
  7. De permissão de execução ao shell script com o comando abaixo:
    chmod +x alarme.sh
  8. Digite os comandos abaixo para criar um arquivo de configuração de serviços do systemd para o projeto:
    cd /lib/systemd/system
    sudo nano alarme.service
  9. No editor nano, cole o conteúdo abaixo:
    [Unit]
     Description=Registra alarme
     Wants=network-online.target
     After=network-online.target[Service]
     ExecStart=/home/pi/alarme.sh
     User=pi[Install]
     WantedBy=multi-user.target
  10. Aperte Ctrl + X e Ctrl + Y para sair e salvar
  11. Execute os comandos abaixo para habilitar o serviço e iniciá-lo:
    sudo systemctl enable alarme.service
    sudo systemctl start alarme.service
  12. Pronto! agora a cada inicialização o script alarme.py será executado em background automaticamente.

Para comprovar que o serviço entra em execução logo após o boot da Raspberry Pi Zero W, reinicie a placa e digite o seguinte comando:

systemctl status alarme.service

O que produzirá uma resposta semelhante à da figura 3, mostrando que o serviço está em execução, fato evidenciado pelo status active (running).

Agendamento de tarefas no Linux - Serviço Python em execução
Figura 3 – serviço referente ao script alarme.py em execução

 

Criação e agendamento de execução no cron do script verifica_evento_alarme.py  

Para criar o script verifica_evento_alarme.py, fazer o agendamento de tarefas no Linux e fazer com que sua execução seja automaticamente realizada, minuto a minuto, com o cron, siga os procedimentos abaixo:

  1. No diretório home, crie o arquivo alarme. py. Para isso, execute os comandos abaixo:
    cd ~
    nano verifica_evento_alarme.py
  1. No editor de texto nano, cole o código abaixo:
    import os
     import datetime
     import RPi.GPIO as GPIO#constantes / definicoes
     path_arq_alarme = "/tmp/alarme.txt"
     GPIO_LED = 24 #Broadcom pin 24 (GPIO24)if (os.path.exists(path_arq_alarme)):
      #configura GPIO24 (onde esta ligado o LED) para ser output
      GPIO.setmode(GPIO.BCM)
      GPIO.setup(GPIO_LED, GPIO.OUT)file = open(path_arq_alarme,"r")
      hora_completa = file.read()
      file.close()hora_minuto = hora_completa.split()
      data_hora_atual = datetime.datetime.now()if ( (int(hora_minuto[0]) == data_hora_atual.hour) and (int(hora_minuto[1]) == data_hora_atual.minute) ):
        #NA hora do alarme (durante todo o minuto da hora agendada), o LED acendera
         GPIO.output(GPIO_LED, GPIO.HIGH)
      else:
         #Fora da hora do alarme (durante todo o minuto da hora agendada), o LED desligara
         GPIO.output(GPIO_LED, GPIO.LOW)
  2. Aperte Ctrl + X e Ctrl + Y para sair e salvar
  3. Digite o seguinte comando para entrar na edição da lista de tarefas do cron:
    crontab -e

    Se você for questionado sobre qual editor de texto deseja utilizar, selecione a opção correspondente ao editor nano.

  4. No editor nano, adicione a seguinte linha ao final do arquivo:
    * * * * * /usr/bin/python /home/pi/verifica_evento_alarme.py
  5. Aperte Ctrl + X e Ctrl + Y para sair e salvar
  6. Faça o reboot da placa com o seguinte comando
    sudo reboot
  7. Pronto! Após o reboot, o script verifica_evento_alarme.py será executado, minuto a minuto.

Teste o projeto

Agora chegou a hora mais divertida: o teste do projeto. Para isso, envie por MQTT (no mesmo Broker e tópico definidos no código de alarme.py) a hora e minutos desejados para acender o LED (lembre-se: o formato é HH MM) e veja o LED se acender durante todo o minuto da hora agendada e se apagar após este minuto.

Para fazer o agendamento de tarefas no Linux, utilize a interface web desenvolvida para o projeto (veja a figura 4). Baixe a interface web em questão clicando aqui.

Interface Web de Agendamento

Funcionamento do agendamento de tarefas no Linux com Raspberry Pi Zero W

Veja abaixo um exemplo de funcionamento do projeto:

 

Gostou deste post sobre como fazer um agendamento de tarefas no Linux via Internet (com MQTT) na Raspberry Pi Zero W? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Posts Relacionados

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

2 Comentários

  1. Parabéns Pedro! Gostei muito da sua ideia para fazer comandos agendados. Ai fica uma dúvida é possível colocar cada gpio com horário de programação diferente?

    1. Guilherme, muito obrigado!

      Sim, é possível colocar cada GPIO com um horário de acionamento diferente, porém exigirá um retrabalho considerável no código-fonte.

      Atenciosamente,
      Pedro Bertoleti