Skip to main content

Existem diversos modelos de gateway (um para cada fabricante diferente de reconhecimento facial, por exemplo). Todos têm uma arquitetura muito parecida, mas pequenas diferenças entre si em função de particularidades de cada fabricante.

Toda a parte comum está organizada num pacote Composer iongrade/gatewaycommon.

Como regra geral, todos os gateways têm um diretório jobs aonde estão os serviços que devem ser executados. Mais ainda, provavelmente há um arquivo daemon.php que orquestra todos os serviços necessários (coloca todo mundo no ar e garante que continuem em execução). Geralmente, que esse arquivo seja o entrypoint do container.

Mais abaixo, teremos a descrição de cada serviço disponibilizado pelo iongrade/gatewaycommon. Cada um deles provavelmente terá um arquivo helper para iniciar sua execução (o arquivo que será orquestrado pelo daemon).

ENTIDADES IMPORTANTES

AppConfiguration

Classe que tem as configuração básicas do gateway (modelo, número de série, facility, versão, etc...). Deve ser registrado manualmente no injetor de dependências.

DeviceInterface

Representa um dispositivo físico (um equipamento de reconhecimento facial, por exemplo).

A definição de um DeviceInterface exige alguns dados básicos, como IP, porta, usuário e senha. Existe uma propriedade de metadata que pode ser usada para guardar "outras coisas específicas"

DeviceRepository

É uma collection de DeviceInterfaces.

DeviceRepositoryCollection

Um agrupador de 02 tipos diferentes de DeviceRepositories: um repositório de "devices normais" (getDevices()) e um repositório de "devices LPR" ( getDevicesLPR()), porque existem diferenças importantes entre as duas coisas.

Cartao/Controlador/Pessoa

Entidades iguais às do Accelero, mas bastante simplificadas.

NormalizedObject/NormalizedObjectInterface

Quase todas as mensagens enviadas pelo Accelero para o gateway são "normalizadas" para uma classe comum pra simplificar o tratamento. Isso existe porque podem haver pequenas diferenças entre as mensagens enviadas pelo Accelero dependendo do modelo, e a padronização/normalização disso acontece no gateway.

FUNCIONAMENTO BÁSICO

O gateway tem algumas responsabilidades básicas:

  • saber quais são os dispositivos pelos quais ele é responsável;
  • saber se esses dispositivos estão online;
  • receber mensagens/instruções do Accelero para "fazer algo nos dispositivos" e fazer;
  • devolver uma resposta para o Accelero dizendo "se deu certo ou não" a execução de alguma instrução;
  • informar periodicamente o Accelero o "status geral das coisas" (status do gateway, status de comunicação com os dispositivos, informações gerais que sejam importantes...).

Toda comunicação com o Accelero é feito via MQTT em tópicos específicos para cada gateway (além de broadcasts):

{FACILITY}/{MODELO}/{SERIAL}/#

Em geral, quatro tópicos são assinados pelo gateway:

TópicoDescrição
{FACILITY}/{MODELO}/{SERIAL}/messagesMensagens com instruções de operação, como "cadastrar pessoa", "excluir pessoa", "envio de configurações", etc...
{FACILITY}/{MODELO}/{SERIAL}/pendencies/#Tópico legado, equivalente ao messages
{FACILITY}/{MODELO}/{SERIAL}/remotecommandTópico backdoor não-documentado para permitir a execução remota de comands no host do gateway.
{FACILITY}/broadcast/toTópico usado basicamente para recepção de keepalives do Accelero.

O que mais importa para a operação normal são mensagens recebidas no tópico messages/pendencies.

Todas as mensagens enviadas pelo Accelero são formatadas em JSON, e o "roteamento" acontece pela chave command, algo como:

//Mensagem enviada pelo Accelero:
//{"command": "enrollfacial", "dados": ...}
function onMessage(Message $message) : void {
$data = json_decode($message->payload, true);
$command = $data['command'] ?? null;
switch ($command) {
case 'enrollfacial':
cadastraFacial($data);)
break;
case 'deleteuser':
deletaUsuario($data);
break;
}
}

SERVIÇOS COMUNS

ControladorScanner

Conecta-se no broker e fica "lendo" mensagens de status/keepalive dos controladores (Aurum/Neon). Com isso, descobre o IP dos controladores e fica fazendo "pings" periódicos.

Sabendo quais controladores estão online (ou não), o gateway pode decidir como lidar com situações como "câmeras de LPR" em que PODE haver comunicações diretas com os controladores.

GarbageCollector

Periodicamente (padrão, 1 hora) o gateway varre as pendências não-tratadas e exclui aquelas que estão paradas há muito tempo (padrão, 1 semana).

StatsFetcher

Periodicamente o gateway recolhe "informações estatísticas" sobre os dispositivos que ele administra. Quais informações são recolhidas depende do que está disponível em cada modelo de facial, mas geralmente é "status de comunicação" (o IP do facial está pingando?) e "status de uso" (quantas faces estão cadastradas em cada facial?). Essas informações são salvas em um cache e enviadas para o Accelero junto com as mensagens de keepalive.

Listener

É o serviço que "fala no MQTT", tanto pra receber pendências do Accelero quando pra enviar mensagens para o Accelero. Não faz nenhum tratamento de mensagens, é apenas o "correio".

Chegou alguma pendência, grava em um arquivo num diretório específica para alguém tratar.

Quando alguém que enviar uma mensagem pro broker, salva a mensagem num arquivo num outro diretório específica, e o Listener faz o efetivo envio.

PendencyHandler / PendencyHandlerDaemon

O PendencyHandler é o serviço que cuida de cada dispositivo específico. Se o gateway administra 10 faciais, haverá 10 cópias do PendencyHandler em execução. O PendencyHandlerDaemon "sobe" cada uma dessas instâncias e garante que estejam sempre no ar.

O handler fica o tempo todo scanneando o "diretório de pendências do facial que ele está cuidando", e se encontrar algum arquivo (cada arquivo é uma pendência), faz o tratamento e prepara a resposta (que será despachada pelo Listener).