Criando um sistema de mini garagem automatizada integrada com um sistema de monitoramento independente

Desenvolvimento de um sistema de monitoramento que exibi todos os eventos que acontecem na garagem automatizada, como abertura de portões ou ocupação de vagas.

Postado em 21 janeiro 2023

Atualizado em 21 janeiro 2023



Introdução

Esse projeto simula o funcionamento de uma garagem automática. A presença de automóveis é detectada com sensores de infravermelho e em seguida essa informação é enviada pelo protocolo MQTT. Informações como a situação atual dos lotes da garagem poderão ser visualizadas pelo navegador em tempo real. Essas informações serão atualizadas sem a necessidade de recarregar a página da internet. Isso é possível graças ao websockets.

Essa garagem também possuirá entrada e saída. Após verificar a presença de um carro, o atuador gira 120 graus e abre a passagem para o carro passar.

Em outras palavras, esse projeto abrange tecnologias de IoT, protocolos de comunicação e desenvolvimento de software. A linguagem de programação será javascript para o desenvolvimento Web e C++ para a programação do hardware.

projeto mini garagem automatizada

Ferramentas

Os componentes hardwares utilizados no projeto são:

Componente Papel Quantidade
Sensor IR Sensor detector de infravermelho 4
Servo SG90 Atuador na entrada e saída 2
ESP8266 Componente principal 1
RaspberryPi4 Servidor 1

Cabos de conexão não serão listados na lista acima. O ESP8266 atua como o componente principal do circuito elétrico. Ele é o componente responsável por armazenar o algoritmo e conectar-se com a internet para fazer a transmissão de dados.

O raspberrypi recebe os dados do ESP8266 e exibi a página para a visualização sobre situação atual da garagem. Todos os componentes devem estar conectados na mesma rede para a comunicação funcionar.

componentes do circuito da mini garagem

Os softwares e bibliotecas necessários para o funcionamento são:

Ferramenta Papel
Apache Servidor
Mosquitto MQTT broker
w2ui.js Biblioteca para o UI
mqtt.js Biblioteca para a conexão
Node.js Ambiente necessário para javascript
npm.js Gerenciador de pacotes javascript
jQuery Biblioteca que interage com páginas HTML

O Apache é a ferramenta básica para a possibilidade de acesso e exibição de uma página web. O apache será instalado e configurado no raspberrypi. Terá a porta 80 aberta para acesso e exibição de conteúdo para dispositivos conectados na mesma rede através do protocolo http.

O mosquitto MQTT servirá de broker, isso é, ele será intermediário entre a comunicação dos componentes ESP8266 e raspberrypi. Porém, para os dados chegarem a página web eles precisam ser desempacotados em websockets. O mosquitto irá fazer esse trabalho para nós.

w2ui é uma biblioteca contendo ferramentas de exibição para páginas na web. Ela será usada para a exibição de listas e entradas de texto (input). Por outro lado, o mqtt.js será responsável por fazer o recebimento de dados através de websockets e atualizar a tela de exibição.

Planejamento

A garagem possuirá um sistema de monitoramento que pode ser visualizado pelo navegador. Essas informações de monitoramento são registradas com os sensores situados na garagem. Através do protocolo de comunicação MQTT, o ESP8266 irá informar quais lotes estão livres ou ocupados e qual é a situação atual da entrada e saída (se está aberto ou fechado). Cada movimento que acontecer na garagem deve ser mostrado no sistema de monitoramento de modo imediato.

Antes de tudo é necessário observar como é o mapa da garagem.
mapa da garagem automatizada

Como indica as cores do mapa, os componentes de amarelo representam os sensores e os componentes vermelhos representam os atuadores que atuarão como portões. A lógica é bastante simples, o carro entra pela entrada e estaciona. Após algum tempo, tira o carro do lote e sai pela saída da garagem. Como pode ser observado no mapa, os sensores estão situados de modo que o carro não saia pela entrada e não entre pela saída.

Circuito elétrico

O circuito elétrico é controlado pelo ESP8266, responsável por enviar instruções para os outros componentes. Através do algoritmo instalado no dispositivo, controlaremos os movimentos físicos dos atuadores e enviaremos informação pelo protocolo MQTT para comunicação entre dispositivos conectados na mesma rede.

diagrama do circuito elétrico

O diagrama acima mostra as seguintes conexões entre componentes:

Porta Componente Papel
D0 Sensor na entrada Detecta a presença de veículos na entrada
D1 Atuador na entrada Abre ou fecha o portão
D2 Sensor do lote 1 Detecta a presença de veículos no lote
D3 Sensor do lote 2 Detecta a presença de veículos no lote
D5 Sensor na saída Detecta a presença de veículos na saída
D6 Atuador na saída Abre ou fecha o portão

Essas portas podem servir tanto como entrada como saída. Ou seja, o ESP8266 pode receber dados de sensores e enviar comandos para os atuadores.

Design do sistema de monitoramento

O sistema de monitoramento será implantado no Raspberrypi e será aberto para acesso e visualização apenas dentro da rede interna através do protocolo HTTP. As informações da garagem chegarão em tempo real através do protocolo websockets e em seguida atualizará as informações exibidas na tela.

As informações serão enviadas da garagem para o mosquitto MQTT que converterá essa informação para websockets. Após essa conversão, é possível ter acesso a informação convertida usando javascript. Detalhes do esquema de comunicação podem ser entendidos com o gráfico abaixo:

esquema de comunicação entre sistemas mini garagem

O próximo passo é fazer o planejamento da página do sistema de monitoramento. Queremos verificar a situação atual de cada componente e os registros de cada evento.

sistema de monitoramento em tempo real da mini garagem

O design acima parece atender às nossas demandas. Cada vez que um evento ocorre, uma nova linha é adicionada na tabela e a situação atual de algum componente será atualizado. A data do evento é registrada no formato de ano/mês/dia horário:minuto:segundos. Lembrando que os valores na tela serão atualizados sem a necessidade de recarregar a página.

Desenvolvimento do sistema de garagem

O sistema de garagem possui 2 grandes tarefas:

  1. Controlar os componentes do circuito
  2. Enviar informações para servidor

1. Controlando os componentes do circuito

Importamos as bibliotecas necessárias para o desenvolvimento do circuito.

#include <Servo.h> // Servo Motor
...

Em primeiro lugar, definimos as constantes. As constantes são valores que não podem ser modificados.

// Sensor pins
#define ENTRANCE_SENSOR_PIN D0 // Porta do sensor de entrada
#define EXIT_SENSOR_PIN D5 // Porta do sensor de saída

// Park slot pins
#define PARK_SLOT1_SENSOR_PIN D2 // Porta do lote do estacionamento 1
#define PARK_SLOT2_SENSOR_PIN D3 // Porta do lote do estacionamento 2

// Motor pins
#define ENTRANCE_SERVO_PIN D1 // Porta do portão de entrada
#define EXIT_SERVO_PIN D6 // Porta do portão de saída

Em seguida, variáveis responsáveis por armazenar a situação atual, período de checagem e tempo transcorrido de cada componente, serão definidos.

int entranceDetectorValue = 0; // Armazena o valor atual do sensor de entrada
unsigned long entraceOpenStartTime; // Armazena a data que o portão foi aberto
const unsigned long entranceOpenPeriod = 5000; //Período que o portão demora para fechar depois que a presença do veículo despareceu

int exitDetectorValue = 0; // Armazena o valor atual do sensor de saída
unsigned long exitOpenStartTime; // Armazena a data que o portão foi aberto
const unsigned long exitOpenPeriod = 5000; //Período que o portão demora para fechar depois que a presença do veículo despareceu

int parkSlot1Detector = 0; // Armazena o valor atual do lote do estacionamento 1
int parkSlot2Detector = 0; // Armazena o valor atual do lote do estacionamento 2

bool isSlot1Occupied = false; // Armazena o valor atual do lote do estacionamento 1
unsigned long slot1ParkStartTime; // Armazena a data e hora que o carro estacionou
const unsigned long slot1CheckPeriod = 10000; // Período que o sensor demora para verificar a presença de um veículo novamente

bool isSlot2Occupied = false; // Armazena a situação do lote do estacionamento 2
unsigned long slot2ParkStartTime; // Armazena a data e hora que o carro estacionou
const unsigned long slot2CheckPeriod = 10000; // Período que o sensor demora para verificar a presença de um veículo novamente

bool isEntranceOpen = false; // Armazena a situação da entrada
bool isExitOpen = false; // Armazena a situação atual da saída

Cada sensor possui 2 variáveis para armazenar a sua situação atual. O motivo para cada componente possuir duas variáveis de gerenciamento de estado é o pelo fato de que após a presença do automóvel deixar de existir, os atuadores não hajam imediatamente. Caso contrário, o portão fecharia encima do automóvel.

como funciona o sensor e o portão na mini garagem

Após sair da zona de alcance do sensor, o portão espera 5 segundos para fechar novamente. Caso o automóvel ainda esteja na zona de alcance do sensor depois de 5 segundos, o portão espera mais 5 segundos para fechar novamente.

Na função “setup” iniciamos as variáveis, especificamos as portas e anexamos as portas dos portões nas suas respectivas variáveis.

void setup() {
  Serial.begin(115200);
  ...
  entranceMotor.attach(ENTRANCE_SERVO_PIN); // Anexa o portão de entrada
  exitMotor.attach(EXIT_SERVO_PIN); // Anexa o portão de saída
  ...
  pinMode(ENTRANCE_SENSOR_PIN, INPUT); // Especifica a porta do sensor de entrada
  pinMode(EXIT_SENSOR_PIN, INPUT); // Especifica a porta do sensor de saída
  pinMode(PARK_SLOT1_SENSOR_PIN, INPUT); // Especifica a porta do lote 1
  pinMode(PARK_SLOT2_SENSOR_PIN, INPUT); // Especifica a porta do lote 2
  ...
}

Na função “loop” é que a grande parte da lógica é executada. Aqui serão escritos todos os comandos e condições necessários para o funcionamento do circuito.

void loop {
	  ...
      entranceDetectorValue = !digitalRead(ENTRANCE_SENSOR_PIN); // Valor do sensor de entrada
	  exitDetectorValue = !digitalRead(EXIT_SENSOR_PIN); // Valor do sensor de saída

	  unsigned long currentTime = millis(); // Usado para calcular a passagem do tempo

	  parkSlot1Detector = !digitalRead(PARK_SLOT1_SENSOR_PIN); // Valor do sensor do lote 1
	  parkSlot2Detector = !digitalRead(PARK_SLOT2_SENSOR_PIN); // Valor do sensor do lote 2
	  ...
}

Após recebermos os valores necessários para as tomadas de decisões, definiremos as condições para a abertura e o fechamento dos portões. O portão de entrada e saída seguem a mesma lógica, apenas a variável utilizada muda.

// Abre o portão caso ele esteja fechado e o sensor esteja detectando presença
if (entranceDetectorValue == 1 && !isEntranceOpen) {
  entranceMotor.write(120); // Abre o portão 120 graus
  entraceOpenStartTime = currentTime; // Começa a contar o tempo
  isEntranceOpen = true; // Troca o estado atual do portão para "aberto"
  ...
}

// Caso o sensor esteja detectando presença, o portão esteja aberto e o tempo passado seja maior ou igual que o período definido (5 segundos)
if (entranceDetectorValue == 1 && isEntranceOpen && (currentTime - entraceOpenStartTime >= entranceOpenPeriod)) {
  entraceOpenStartTime = currentTime; // Atualiza o tempo
  Serial.println("Keep Entrance Opened");
}

// Caso não haja mais presença detectada, o portão esteja aberto e o tempo passado passe de 5 segundos
if (entranceDetectorValue == 0 && isEntranceOpen && (currentTime - entraceOpenStartTime >= entranceOpenPeriod)) {
  entranceMotor.write(0); // Fecha o portão
  Serial.println("Close Entrance");
  isEntranceOpen = false; // Troca a situação atual do portão para "fechado"
  ...
}

São três condições para o portão de entrada. A lógica funciona da seguinte maneira:

  1. A primeira condição exige que o sensor detecte presença e que o portão esteja fechado.
  2. A segunda condição exige que o sensor detecte presença, o portão aberto e o tempo de 5 segundos ultrapassado
  3. A terceira condição exige que o sensor não detecte mais presença, o portão esteja aberto e o tempo de 5 segundos ultrapassado

Para o portão de saída, a lógica é exatamente a mesma.

Uma vez que implementamos a lógica dos atuadores e sensores, a próxima implementação será o envio de dados para o servidor.

2. Enviando informações para o servidor

Qualquer mudança que acontecer na garagem deverá ser noticiado ao servidor. Se detalharmos esses eventos, teremos a seguinte lista:

  • Notificação de portão de entrada aberto
  • Notificação de portão de entrada fechado
  • Notificação de portão de saída aberto
  • Notificação de portão de saída fechado
  • Notificação de lote 1 ocupado
  • Notificação de lote 1 vago
  • Notificação de lote 2 ocupado
  • Notificação de lote 2 vago

As bibliotecas necessárias para o envio de dados e a marcação do tempo atual são as 5 abaixo:

...
#include <ESP8266WiFi.h> // Conexão com a internet
#include <ArduinoJson.h> // Formato Json
#include <PubSubClient.h> // cliente MQTT
#include <NTPClient.h> // Data e Horário
#include <WiFiUdp.h> // Data e Horário

Conexão com a internet

A conexão com a internet é a base para a comunicação entre máquinas. A função abaixo é responsável pela conexão com a internet:

void setupWifi() {
  delay(100);
  
  String wifiName = "xxx"; // Nome do wifi
  String password = "xxx"; // Senha do wifi
  WiFi.begin(wifiName, password);
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  ...
}

A função acima é invocada em “setup” e persiste até que a conexão com a internet seja sucedida.

Data e horário

Para sabermos a data e a hora que cada evento aconteceu, precisamos definir as variáveis responsáveis pelo tempo. A data e horário podem ser obtidos através do servidor “pool.ntp.org”, por isso a conexão com a internet é necessária. Não entraremos em detalhes sobre essa biblioteca aqui.

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

Na função “setup”, iniciamos a variável responsável pelo horário e especificamos o fuso horário.

timeClient.begin(); // Inicializa
timeClient.setTimeOffset(32400); // UTC + 9

A data é definida em UTC (Tempo universal coordenado). No caso desse projeto, o horário está programado para Tóquio (+9). O valor 32400 é resultado do cálculo abaixo:

timeoffset=3600x timeoffset = 3600 * x

No caso do Brasil, o “timeOffset” de Brasília é de -10800 (UTC - 3).

Na função “loop”, calcularemos a data e o horário. Em seguida, armazenamos esses valores em uma variável local, pois iremos precisar desses valores no envio de dados em cada evento.

timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
struct tm *ptm = gmtime ((time_t *)&epochTime);
String formattedTime = timeClient.getFormattedTime();
int monthDay = ptm->tm_mday;
int currentMonth = ptm->tm_mon+1;
int currentYear = ptm->tm_year+1900;
String currentDate = String(currentYear) + "/" + String(currentMonth) + "/" + String(monthDay);
String fullDatetime = currentDate + " " + formattedTime;

Essas variáveis serão atualizadas todas as vezes que a função loop é executada.

O envio de dados através do protocolo MQTT

Após nos conectarmos com a internet e obtermos a data e o horário em cada loop, enviamos esses dados para o mosquitto MQTT. Primeiro definimos as variáveis globais:

const char *mqtt_broker = "raspberrypi.local"; // Url configurado no apache do raspberrypi
const char *topic = "park/situation"; // Tópico que as informações serão enviadas
const int mqtt_port = 1883; // Porta de conexão MQTT para o envio de dados

WiFiClient espClient; // cliente WIFI
PubSubClient client(espClient); // cliente MQTT

Iniciamos o cliente MQTT com as informações do servidor:

client.setServer(mqtt_broker, mqtt_port);

E em seguida, invocamos a função abaixo para a conexão com o servidor através do protocolo MQTT na função “setup”:

void connectMqtt() {
  while (!client.connected()) {
    String client_id = "esp8266-client-";
    client_id += String(WiFi.macAddress());
    client.connect(client_id.c_str())
  }
}

Antes de começar a enviar dados, precisamos definir o formato da informação. Cada evento será notificado através do protocolo MQTT para o broker instalado no raspberrypi. A estrutura dos dados será feita da seguinte forma:

Variável Tipo Papel
parkNumber String Especifica qual componente causou o evento
parkSituation bool Estado atual do lote ou do portão
datetime String Data e horário que o evento ocorreu

Os dados que serão enviados serão armazenados em uma instância da classe “ParkData”:

class ParkData {
  public:
    String parkNumber;
    bool parkSituation;
    String datetime;
    ParkData(String pn, bool ps, String d);
};

Essa classe servirá de parâmetro para a função responsável pelo envio de dados através do protocolo MQTT:

void sendParkSituation(ParkData parkData) {
    // Armazena os dados em formato JSON
    StaticJsonDocument<256> staticJsonDocument;
    staticJsonDocument["slot"] = parkData.parkNumber;
    staticJsonDocument["vacancy"] = parkData.parkSituation;
    staticJsonDocument["datetime"] = parkData.datetime;

    char requestBody[128];
    serializeJson(staticJsonDocument, requestBody);

	// Envia os dados
    client.publish(topic, requestBody);

    delay(1000);
}

Em seguida, podemos testar o envio desses dados na função “setup” para confirmar a conexão.

connectMqtt();
...
ParkData parkData("Connection", true, "");
sendParkSituation(parkData);

A função “sendParkSituation” pode ser invocada dentro das condições dentro do loop, notificando o servidor quando necessário.

Desenvolvimento do sistema de monitoramento

Como mostrado na fase de planejamento, o sistema de monitoramento usa dois sistemas:

  • Broker (Mosquitto MQTT)
  • Página Web (Apache)

O broker desempenha o papel de intermediário entre o cliente e o servidor. No caso desse projeto, o cliente é a garagem e o servidor é o sistema de monitoramento.

Raspberrypi
MQTT
Websockets
Sistema de monitoramento
Broker
Garagem

No raspberrypi iremos instalar e configurar servidor Apache e o Mosquitto MQTT.

Instalando o mosquitto MQTT

O sistema operacional do raspberrypi é o linux. Todos os pacotes serão instalados através do terminal, pelo protocolo SSH.

ssh [email protected]

Uma vez que estamos dentro do servidor, podemos instalar os pacotes do broker.

sudo apt-get install mosquitto

Com o intuito de facilitar o trabalho, instalaremos um pacote para teste. Assim, podemos testar o broker mesmo sem mandar mensagens da garagem. Isso é ótimo quando o projeto ainda esta em desenvolvimento, pois agiliza o processo.

sudo apt-get install mosquitto-clients

O pacote acima permite que publiquemos e nos inscrevemos em tópicos de MQTT. O comando abaixo envia mensagens para o broker através do tópico “park/situation”.

sudo mosquitto_pub -h raspberrypi.local -t 'park/situation' -m "test"
  • -h: Host
  • -t: Tópico
  • -m: mensagem

Para finalizar, precisamos configurar o broker para aceitar mensagens de máquinas desconhecidas e especificar os protocolos.

sudo nano /etc/mosquitto/mosquitto.conf

No arquivo “mosquitto.conf” adicionamos as seguintes linhas:

allow_anonymous true

listener 1883
listener 9001
protocol websockets

Permitir conexões anônimas pode não ser muito seguro na maioria dos casos, porém nesse projeto vamos configurar do modo mais simples possível. Lembrando que apenas dispositivos na mesma rede podem acessar o broker. As portas 1883 e 9001 estão abertas para conexão. O protocolo especificado foi websockets, pois permite que páginas web possam receber informações em tempo real.

Após finalizar as especificações, reiniciamos o broker para atualizar as informações.

sudo service mosquitto restart

A instalação e configuração do broker estão prontos.

Instalando o Apache e configurando a página web

A instalação do apache no linux é extremamente simples. Os dois comandos abaixo são o suficiente para a instalação e exibição:

sudo apt update
sudo apt install apache2

Em seguida instalamos o node.js e o npm.js para desenvolvimento em javascript.

sudo apt update
sudo apt install nodejs npm

Confirmamos se os pacotes foram instalados com sucesso verificando a versão:

node -v
v12.22.12

npm -v
7.5.2

Enfim, instalamos as bibliotecas necessárias.

npm i w2ui
npm i jquery

Para simplificar, não instalaremos a biblioteca “mqtt.js”. Importaremos através de um CDN (Rede de fornecimento de conteúdo). O CDN tem a vantagem de ser rápido, porém pode trazer desvantagens ao longo prazo, caso a biblioteca não possa mais ser acessada.

O sistema de monitoramento possui apenas uma página e não precisa de botões ou outras funcionalidades que interagem com o usuário. Por essa razão, basta editarmos o arquivo padrão de exibição do apache:

sudo nano /var/www/html/index.html

Apagamos todo o código existente e colamos o código abaixo:

<!DOCTYPE html>
<html>
   <head>
      <title>Garagem virtual</title>
      <link rel="stylesheet" type="text/css" href="/node_modules/w2ui/w2ui-1.5.min.css">
      <script type="text/javascript" src="/node_modules/jquery/dist/jquery.min.js"></script>
      <script type="text/javascript" src="/node_modules/w2ui/w2ui-1.5.min.js"></script>
      <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> <!-- CDN -->
      <style>
         .block {
         padding-top: 20px;
         padding-bottom: 10px;
         color: #999;
         }
         .w2ui-field input {
         width: 100px;
         text-align: right;
         }
         .w2ui-field > div > span {
         margin-left: 20px;
         }
      </style>
   </head>
   <body>
      <h1>Garagem virtual</h1>
      <div class="block">
         <b>General</b>
      </div>
      <div class="w2ui-field">
         <label>Entrada:</label>
         <div><input readonly id="entrance"></div>
      </div>
      <div class="w2ui-field">
         <label>Saida:</label>
         <div><input readonly id="exit"></div>
      </div>
      <div class="w2ui-field">
         <label>Lote 1:</label>
         <div><input readonly id="slot1"></div>
      </div>
      <div class="w2ui-field">
         <label>Lote2:</label>
         <div><input readonly id="slot2"></div>
      </div>
      <div id="grid" style="width: 100%; height: 250px;"></div>
      <script>
	     // Exibi a tabela de eventos
         let grid = $('#grid').w2grid({
              name: 'grid',
              header: 'Garagem virtual',
              columns: [
              	{ field: 'datetime', text: 'Data', size: '25%' },
                { field: 'slot', text: 'Slot', size: '25%' },
                { field: 'situation', text: 'Situation', size: '50%' }	
              ],
              records: []
          });
          
         // Mantém conexão com o broker para receber mensagens em tempo real
         // ws = websockets
         let sub = mqtt.connect('ws://raspberrypi.local:9001');
         
         let topic = "park/situation";
         // Inscrição no tópico
         sub.subscribe(topic);
         
         sub.on('message', function (topic, message) {
             let parkInfo = JSON.parse(message);

             if (parkInfo.slot == "Entrance") {
               let situation = parkInfo.vacancy ? "Aberto" : "Fechado";
               $("#entrance").val(situation).trigger('change');
             }

             if (parkInfo.slot == "Exit") {
               let situation = parkInfo.vacancy ? "Aberta" : "Fechada";
               $("#exit").val(situation).trigger('change');
             }

             if (parkInfo.slot == "Slot 1") {
               let situation = parkInfo.vacancy ? "Ocupado" : "Vazio";
               $("#slot1").val(situation).trigger('change');
             }

             if (parkInfo.slot == "Slot 2") {
               let situation = parkInfo.vacancy ? "Ocupado" : "Vazio";
               $("#slot2").val(situation).trigger('change');
             }
             grid.add({ recid: grid.records.length, slot: parkInfo.slot, situation: parkInfo.vacancy, datetime: parkInfo.datetime});
         });
      </script>
   </body>
</html>

O código acima não é muito complexo. Primeiro, criamos uma instância de conexão websockets:

let sub = mqtt.connect('ws://raspberrypi.local:9001');

Especificamos o tópico de inscrição para receber mensagens da garagem:

sub.subscribe("park/situation");

Em seguida, fazemos com que sejamos notificados caso a garagem envie algum tipo de mensagem para o broker.

sub.on('message', function (topic, message) {...}

Ao recebermos mensagens da garagem, convertemos essa mensagem do formato “String” para um objeto.

let parkInfo = JSON.parse(message);

Logo depois, verificamos qual sensor está mandando mensagens e atualizamos o seu estado atual. Selecionamos a tag do html especificada e atualizamos o seu valor. A mesma lógica funciona para a entrada, lote1 e lote 2.

if (parkInfo.slot == "Exit") {
    let situation = parkInfo.vacancy ? "Aberta" : "Fechada";
    $("#exit").val(situation).trigger('change');
}

Finalmente, adicionamos uma linha na tabela de eventos contendo o horário, sensor e valor.

grid.add({ recid: grid.records.length, slot: parkInfo.slot, situation: parkInfo.vacancy, datetime: parkInfo.datetime});

Toda vez que uma mensagem for enviada da garagem, essa mensagem será adicionada na tabela.

Implementação de outras funcionalidades

A garagem e o sistema de monitoramento ainda carecem de funcionalidades básicas. Por exemplo, o sistema da garagem não devia abrir o porão quando todas as vagas estivessem ocupadas. O sistema de monitoramento perde os dados toda vez que atualizamos a página.

No caso do sistema de garagem, basta adicionarmos uma condição para verificar se o estacionamento esta lotado. Porém, no caso do sistema de monitoramento, precisaríamos de um banco de dados para armazenar todas as mensagens recebidas.

O quê aprendemos com esse projeto?

Aprendemos a usar sensores e atuadores para criar um sistema automático de estacionamento. Também aprendemos a fazer a transferência de dados através do protocolo MQTT e Websockets. O websockets possibilita o envio e o recebimento de dados em tempo real através de páginas da web.

Além disso, foi necessário a implantação de um broker para fazer a conversão de informações do protocolo MQTT para Websockets.

O código completo da garagem está disponível para visualização no GitHub.

Postagens mais vistas

Os 5 principais componentes do computador

Os 5 principais componentes do computador são a unidade de controle, unidade aritmética e lógica, memória, dispositivo de entrada e dispositivo de saída.

Portas TCP e UDP

A porta é um número de 16 bits que é adicionado no final do endereço IP, insinuando qual aplicativo está vinculado e atuando nessa porta.

LAN

Rede local de computadores (LAN) é um conjunto de computadores ou dispositivos conectados uns aos outros de forma isolada em um pequeno local.

Retornar aos projetos