Pular para o conteúdo principal

Comissionamento de portal Zebra

Como ligar um leitor fixo Zebra FX ao Gestão de Ativos, do cadastro do ponto de leitura até a movimentação aparecendo sozinha na tela de registros.

Este guia começa onde o Instalação e validação termina: o middleware já está instalado e no ar. Aqui o assunto é a integração entre os dois sistemas.

Fluxo verificado ponta a ponta em 10/09/2026, com Gestão de Ativos 1.1.10 sobre SQL Server 2019 (banco pré-criado, collation case-sensitive) e Middleware LITE 1.0.0 na mesma máquina.

A cadeia​

O leitor não fala com o Gestão de Ativos. Ele abre um socket para o middleware, que junta as leituras em lote e faz uma única chamada HTTP por passagem.


Parte 1 — Preparar o Gestão de Ativos​

A ordem importa: o endpoint que o middleware vai chamar só existe depois que o ponto de leitura foi criado, porque a chave é derivada do ID dele.

1. Criar o nível e o ponto de leitura do portal​

Menu Níveis Orga.

Um nível é o local físico (fábrica, CD, filial). Dentro dele, cada ponto de leitura é um lugar por onde o ativo passa ou onde ele fica parado.

Crie o nível, depois adicione um ponto de leitura para a doca:

  • Tipo de leitura: Leitor Fixo Zebra — é o que habilita a geração da chave de API.
  • Status do ativo: o status que todo item recebe ao passar por aqui (ex.: ativo).
  • Gerar alerta: ligue apenas se toda passagem tiver de virar alerta.

Crie também um segundo ponto de leitura comum (ex.: Estoque, tipo QR Code). Ele será o local de origem dos itens e, se você usar o mapeamento de entrada/saída do passo 5, o local de trânsito.

2. Liberar os níveis do usuário "Dispositivo Fixo"​

Menu Administração › Usuários

A instalação cria um usuário de sistema chamado Dispositivo Fixo (device@system.local). É a identidade com que o portal grava as movimentações — é o nome que aparece na auditoria.

Ele nasce sem nenhum nível autorizado. Edite o usuário e marque o nível do portal (ou "ver todos os níveis").

Pula esse passo e o portal não funciona

Sem nível liberado, toda leitura volta 403 — Usuário não possui níveis autorizados. O sintoma engana: o leitor lê, o middleware mostra a action disparando, e nada aparece no Gestão de Ativos.

3. Copiar o endpoint do portal​

Menu Movimentação › Pontos de Leitura

A lista mostra os pontos de leitura com uma coluna Endpoint. No ponto marcado como Leitor Fixo Zebra, clique no ícone de copiar. Vai para a área de transferência a URL completa, já com a chave:

http://SERVIDOR:4001/movimentacao/itens/movimentar/2?apiKey=5dad1687dd76…9841

O número antes do ? é o ID do ponto de leitura. A chave é um HMAC de movimentacao:<id> assinado com o JWT_SECRET da instalação, e vale só para esse ponto — ela não abre nenhuma outra rota da API.

Guarde isso para o dia da reinstalação

A chave é derivada do JWT_SECRET. Reinstalar por cima preserva o segredo e a URL continua válida. Instalar do zero gera um segredo novo e invalida todas as URLs de portal — é preciso copiar de novo e reconfigurar cada action.

4. Garantir que os ativos existem​

Menu Etiquetas / Impressão

O portal movimenta ativos, não cria. Um EPC que não está cadastrado é ignorado, e a resposta lista ele em epcsNaoEncontrados. Se nenhum EPC do lote for conhecido, a chamada volta 404.

Os ativos entram no sistema pelo fluxo de etiquetas: cadastre o produto, gere os itens de impressão e imprima. Antes de comissionar o portal, confirme que as tags do teste já aparecem em Ativos.

5. Ligar o mapeamento de entrada e saída (opcional)​

Menu Administração › Configuração

Por padrão, toda passagem pelo portal registra uma movimentação para o próprio portal. Com o mapeamento ligado, o sistema passa a alternar o sentido a cada passagem e grava o tipo do evento:

  • item parado no portal, lido de novo → saída, e ele vai para o local de trânsito;
  • item em trânsito, lido no portal → entrada, e ele volta para o portal.

Configure nesta ordem, senão a segunda etapa é recusada:

  1. Escolha o local dos itens em trânsito e salve. Vale qualquer ponto de leitura ativo que não seja um portal Zebra — use o Estoque do passo 1.
  2. Ative a chave mapeamento de entrada e saída.

Para conferir: passe a mesma tag duas vezes pelo portal e abra Movimentação › Registros. Os dois lançamentos têm que sair com sentidos opostos.


Parte 2 — Conectar o leitor ao middleware​

O leitor se anuncia sozinho assim que o agente embarcado sobe. Você não cadastra o leitor no painel — ele aparece.

6. Instalar o DA-APP com o endereço do middleware​

No leitor Zebra FX

O DA-APP é o agente que roda dentro do FX e abre o socket para o servidor. Ele é gerado com o endereço já embutido, então informe no build:

ParâmetroValorObservação
middlewareHost192.168.0.50IP ou DNS do servidor, alcançável da rede do leitor
backendTcpPort5555socket do DA-APP
backendHttpPort4141painel web
readerUsername / readerPasswordadmin / …credenciais do próprio FX, usadas pelo agente nas APIs locais

Rede: o leitor precisa alcançar SERVIDOR:5555, e o operador precisa alcançar SERVIDOR:4141. Em servidor Windows, libere as duas portas na entrada do firewall; em nuvem, também no security group.

O endereço fica compilado no pacote

Não existe um .deb genérico: o IP e as portas são gravados no agente na hora do build. Um pacote por site — ou por servidor de middleware.

Existe uma saída, se você precisar redirecionar um leitor já instalado sem regerar: as variáveis de ambiente HIOT_SERVER_HOST e HIOT_SERVER_PORT vencem o valor gravado.

Como gerar o .deb​

O gerador vive no repositório do middleware, em back/installer/da-app-builder-service. Ele monta o agente, os scripts de start/stop e empacota com dpkg-deb — por isso precisa rodar em Linux (no Windows, use WSL).

O README.md do diretório descreve subir um serviço HTTP numa VPS e pedir o build por token. Isso é útil se você quiser que outras pessoas gerem pacotes sem acesso ao repositório, mas esse serviço não está hospedado em lugar nenhum hoje — a URL padrão do cliente é um placeholder. Para uma implantação pontual, chame o gerador direto.

Salve como gera-daapp.js na raiz de da-app-builder-service:

const path = require("path");
const fs = require("fs/promises");
const { buildDaAppPackage } = require("./src/package-builder");
const { normalizeBuildRequest } = require("./src/builder-utils");

// uso: node gera-daapp.js <IP_DO_MIDDLEWARE> <DIR_SAIDA> [porta_tcp] [porta_http]
(async () => {
const cfg = normalizeBuildRequest({
middlewareHost: process.argv[2],
backendTcpPort: Number(process.argv[4] || 5555),
backendHttpPort: Number(process.argv[5] || 4141),
readerUsername: process.env.FX_USER || "admin",
readerPassword: process.env.FX_PASS || "Change@123",
});
const built = await buildDaAppPackage(cfg);
await fs.mkdir(process.argv[3], { recursive: true });
const dest = path.join(process.argv[3], built.fileName);
await fs.copyFile(built.outputFile, dest);
await built.cleanup();
console.log("OK ->", dest);
})().catch((e) => { console.error("FALHOU:", e.message); process.exit(1); });

E rode:

node gera-daapp.js 192.168.0.50 ./dist

Não precisa de npm install: o package-builder só usa módulos nativos do Node. A única dependência externa é o dpkg-deb, que já vem em qualquer Debian/Ubuntu.

Se as credenciais do leitor não forem as padrão, passe antes do comando:

FX_USER=operador FX_PASS='senha-real' node gera-daapp.js 192.168.0.50 ./dist
Confirme as credenciais do FX antes de gerar

O agente usa usuário e senha para chamar as APIs locais do próprio leitor. Com credencial errada, o pacote instala, conecta no middleware e aparece no painel — mas falha na hora de comandar o rádio. O sintoma não aponta para a senha.

O que vem dentro​

hiot-bridge-agent.js          → o agente; vai para /apps/ no leitor
start_hiot-bridge-agent.sh → node /apps/hiot-bridge-agent.js &
stop_hiot-bridge-agent.sh
connect-scripts.txt → resumo da configuração embutida

O control do pacote traz APP_TYPE: DA: é um user app do Zebra IoT Connector, instalado pelo console web do leitor. O procedimento de upload é o da própria Zebra — packaging and deployment.

Para conferir um pacote antes de mandar para o cliente:

dpkg-deb -I pacote.deb                      # metadados, confirma APP_TYPE: DA
dpkg-deb -c pacote.deb # lista os arquivos
dpkg-deb -x pacote.deb /tmp/v && grep SERVER_HOST /tmp/v/hiot-bridge-agent.js

O último comando é o que importa: mostra o IP que realmente ficou gravado.

7. Conferir o leitor e definir o modo de leitura​

Painel do middleware — http://SERVIDOR:4141

Com o DA-APP rodando, o leitor aparece no menu lateral. Clique nele e confira que o rádio está conectado e as antenas certas estão habilitadas com a potência desejada.

ModoQuando usar
Start e stop manualcomissionamento e testes — você controla pelo painel
Start por GPI e stop por GPIportal com sensor de presença nas duas pontas
Start por GPI e stop por tempoportal com um sensor só; a passagem tem duração previsível
Contínuoleitura permanente, com envio em lote por intervalo

Em portal de doca, o normal é GPI: o sensor dispara a leitura, e o lote é enviado quando ela termina. O debounce evita que oscilação elétrica do sensor abra várias leituras.

Sem hardware ainda?

Use Adicionar leitor simulador. Ele aceita uma lista de tags por antena e se comporta como um FX real — dispara as actions do mesmo jeito. Foi assim que este fluxo foi validado.

8. Cadastrar a action que movimenta​

Painel do middleware — Cadastrar ações

Uma action é a chamada HTTP que o middleware dispara quando fecha um lote de leituras. Crie uma por portal:

CampoValor
Nomealgo que identifique o portal, ex.: GA — Doca 01
MétodoPOST
URLa URL copiada no passo 3, com o IP no lugar de localhost
Estratégia de enviolote — uma chamada por passagem, com todas as tags
Timeout10000 ms

No corpo da requisição, monte uma lista de objetos com a chave leituras e três campos:

ChaveOrigemVira
epcEPCo código da tag
readsSEEN_COUNTquantas vezes foi vista
antenaANTENNAantena que leu

O middleware vai montar exatamente isto e postar na URL:

{
"leituras": [
{ "epc": "E28011700000021234500001", "reads": 6, "antena": 1 },
{ "epc": "E28011700000021234500002", "reads": 6, "antena": 1 }
]
}

Depois de salvar, volte à tela do leitor, encontre Associar action e escolha a action recém-criada. É esse vínculo que faz o lote sair.

Duas armadilhas que custam uma tarde

Não use o modo de entrega "simples". Ele existe para integrações genéricas e manda um corpo com batchId, macAddress e reads — formato que o Gestão de Ativos não entende. A movimentação só funciona por action.

Não use localhost na URL, mesmo com os dois sistemas na mesma máquina. O middleware resolve localhost para IPv6 e a API do Gestão de Ativos escuta em IPv4 — a action falha com ECONNREFUSED ::1:4001. Use 127.0.0.1 ou o IP do servidor.


Parte 3 — Validar a passagem​

9. Passar a tag e conferir os dois lados​

  1. Inicie a leitura (pelo painel, ou passando pelo sensor) e encerre.
  2. No painel do leitor, abra o diagnóstico de entrega. Você deve ver action-request com o corpo montado e, na sequência, action-response com status 200.
  3. No Gestão de Ativos, abra Movimentação › Registros. Os lançamentos aparecem com usuário Dispositivo Fixo e destino no ponto do portal.
  4. Abra o ativo em Ativos e confirme que o local atual mudou para o portal.

O corpo da resposta do Gestão de Ativos é o melhor diagnóstico que existe — ele diz quantos processou e quais EPCs não conhecia:

{
"message": "Movimentações processadas com sucesso",
"processados": 3,
"epcsNaoEncontrados": [],
"movimentacoes": [
{ "epc": "E280…0001", "movimentacao_id": 7, "reads": 6, "antena": 1 }
]
}

10. Quando não funciona​

O que você vêCausaCorreção
Leitor não aparece no painelDA-APP não subiu, ou porta 5555 bloqueadaConfira o serviço no FX e libere a porta entre leitor e servidor
Leitor conecta, mas não obedece start/stopCredenciais Local REST erradas no pacotePasso 6 — regere o .deb com FX_USER/FX_PASS corretos
Leitor aponta para o servidor erradoIP compilado num .deb antigoRegere, ou sobrescreva com HIOT_SERVER_HOST
ECONNREFUSED ::1:4001localhost resolvendo para IPv6Troque por 127.0.0.1 ou pelo IP do servidor
403 níveis autorizados"Dispositivo Fixo" sem nívelPasso 2 — libere o nível do portal para o usuário
401 Token inválidoChave não bate com o JWT_SECRET atualCopie a URL de novo no passo 3 e refaça a action
404 nenhum EPC válidoTags não cadastradas como ativosPasso 4 — gere as etiquetas antes
Action dispara, nada é gravadoModo de entrega "simples" em vez de actionPasso 8 — associe a action ao leitor
422 processo de trânsitoMapeamento ligado sem trânsito válidoPasso 5 — salve o trânsito antes de ativar a chave
Lê, grava, mas sem entrada/saídaChave de mapeamento desligadaPasso 5 — o tipo do evento fica vazio sem ela

Referência — contrato do endpoint​

Útil se você for integrar outro leitor, ou depurar com curl antes de mexer no middleware.

A rota POST /movimentacao/itens/movimentar/<id> aceita o formato do middleware e também o formato nativo do Zebra IoT Connector. O EPC é normalizado para maiúsculas nos dois casos.

// formato do middleware / mobile / web
{ "leituras": [ { "epc": "E280…0001", "reads": 2, "antena": 4,
"timestamp": "2026-09-10 09:30:00" } ] }
// formato nativo Zebra IoT Connector — array na raiz
[ { "data": { "idHex": "e280…0003", "reads": 7, "antenna": 2 },
"timestamp": "2026-09-10T12:31:00.000Z" } ]

A autenticação vale por ?apiKey= na query ou por Authorization: Bearer <chave>. Teste rápido de linha de comando:

curl -X POST "http://192.168.0.50:4001/movimentacao/itens/movimentar/2?apiKey=SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"leituras":[{"epc":"E28011700000021234500001","reads":1,"antena":1}]}'

Portas e caminhos​

ItemPadrão
API do Gestão de Ativos:4001
Front do Gestão de Ativos:3000
Painel do middleware:4141
Socket DA-APP:5555
Dados do middlewareC:\ProgramData\H1TECH-Middleware-LITE
Logs de serviço…\service-logs
Instalação do Gestão de AtivosC:\Program Files\H1Tech\GestaoAtivos
Log de instalaçãoC:\ProgramData\H1Tech\GestaoAtivos\logs

O que foi e o que não foi validado​

Verificado ponta a ponta: agregação do lote pelo middleware, montagem do corpo, autenticação por chave de dispositivo, gravação da movimentação no SQL Server e o mapeamento de entrada/saída alternando o sentido a cada passagem.

Não validado com hardware real: a instalação do DA-APP no FX físico e o disparo por GPI. O teste usou o leitor simulador, que dispara as actions exatamente do mesmo jeito, mas não substitui um FX na doca.