Skip to content

suporterfid/octane-tag-writing-test

Repository files navigation

Octane Tag Writing Test

Um sistema abrangente de testes .NET 8 para avaliação de operações de escrita em tags RFID utilizando o Impinj Octane SDK. Este projeto implementa múltiplas estratégias de teste para avaliar diferentes aspectos de performance, confiabilidade e funcionalidade de escrita em tags RFID.

Visão Geral

Esta aplicação fornece um framework estruturado de testes para operações de escrita em tags RFID, implementando várias estratégias de teste usando o padrão Strategy para organizar diferentes cenários de teste. A arquitetura facilita a adição de novos casos de teste mantendo uma interface consistente.

Pré-requisitos

  • .NET 8.0 SDK
  • Impinj Octane SDK (v5.0.0)
  • LLRP SDK (incluído com o Octane SDK)
  • Leitor RFID Impinj (hostname/endereço IP necessário)
  • Docker (opcional, para execução containerizada)

Preparação para publicação corporativa

Para compartilhar este repositório em um GitHub corporativo sem expor dados de clientes:

  • Configuração sanitizada: o arquivo OctaneTagWritingTest/config.example.json contém apenas hostnames e identificadores fictícios. Copie-o localmente para config.json e preencha as informações reais fora do controle de versão.
  • Arquivos locais ignorados: config.json, reader_settings.json e a pasta reader_settings/ já estão listados no .gitignore padrão. Valide que nenhuma variante com credenciais foi adicionada ao repositório antes de publicar.
  • Dados de amostra fictícios: as listas epc_list.txt e tid_list.txt, bem como as constantes de teste em TagUtils.Tests, utilizam valores claramente fictícios e anotados nos comentários. Mantenha esta distinção ao gerar novos conjuntos de teste.
  • Documentação neutra: substitua quaisquer referências a endereços IP ou infraestrutura cliente por placeholders (por exemplo, detector.example.com). Os exemplos de CLI e Docker neste README já seguem este padrão.
  • Licenciamento corporativo: atualize o arquivo LICENSE com o texto aprovado pela empresa antes de abrir o código internamente.

Estrutura do Projeto

OctaneTagWritingTest/
├── JobStrategies/
│   ├── JobStrategy0ReadOnlyLogging.cs          # Logging apenas de leitura
│   ├── JobStrategy1SpeedStrategy.cs            # Teste de velocidade de escrita
│   ├── JobStrategy2MultiAntennaWriteStrategy.cs # Escrita multi-antena
│   ├── JobStrategy3BatchSerializationPermalockStrategy.cs # Operações em lote
│   ├── JobStrategy4VerificationCycleStrategy.cs # Ciclo de verificação
│   ├── JobStrategy5EnduranceStrategy.cs        # Teste de resistência
│   ├── JobStrategy6RobustnessStrategy.cs       # Teste de robustez
│   ├── JobStrategy7OptimizedStrategy.cs        # Estratégia otimizada
│   ├── JobStrategy8MultipleReaderEnduranceStrategy.cs # Resistência multi-leitor
│   └── JobStrategy9CheckBox.cs                 # Teste CheckBox
├── Helpers/
│   ├── EpcListManager.cs           # Gerenciamento de listas EPC
│   ├── TagOpController.cs          # Controle de operações de tags
│   ├── CommandLineParser.cs        # Parser de linha de comando
│   └── InteractiveConfig.cs        # Configuração interativa
├── BaseTestStrategy.cs             # Classe base para estratégias
├── IJobStrategy.cs                 # Interface do padrão Strategy
├── JobManager.cs                   # Gerenciador de execução de testes
├── Program.cs                      # Ponto de entrada da aplicação
├── ApplicationConfig.cs            # Configuração da aplicação
├── ReaderSettings.cs               # Configurações do leitor
├── ReaderSettingsManager.cs        # Gerenciador de configurações
└── Dockerfile                      # Configuração Docker

Configuração do Projeto

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
  </PropertyGroup>
</Project>

Pacotes NuGet

  • OctaneSDK (v5.0.0)
  • Newtonsoft.Json (v13.0.3)
  • Microsoft.VisualStudio.Azure.Containers.Tools.Targets (v1.21.0)

Estratégias de Teste Implementadas

0. Read-Only Logging (JobStrategy0)

  • Apenas logging de operações de leitura
  • Não realiza escrita, apenas monitora tags

1. Speed Strategy (JobStrategy1)

  • Otimizado para máxima velocidade de escrita
  • Mede e registra timing das operações de escrita
  • Resultados salvos em arquivo CSV

2. Multi-Antenna Write Strategy (JobStrategy2)

  • Testa escrita através de múltiplas antenas
  • Avalia coordenação e troca de antenas

3. Batch Serialization Permalock Strategy (JobStrategy3)

  • Testa operações de escrita em lote
  • Avalia performance de serialização
  • Inclui operações de permalock

4. Verification Cycle Strategy (JobStrategy4)

  • Implementa ciclos de escrita-verificação
  • Garante integridade dos dados escritos

5. Endurance Strategy (JobStrategy5)

  • Teste de resistência/durabilidade
  • Executa múltiplos ciclos de escrita

6. Robustness Strategy (JobStrategy6)

  • Teste de robustez com retry logic
  • Implementa recuperação de erros
  • Máximo de 5 tentativas por operação

7. Optimized Strategy (JobStrategy7)

  • Estratégia otimizada para performance
  • Configurações ajustadas para melhor throughput

8. Multiple Reader Endurance Strategy (JobStrategy8)

  • Estratégia avançada com múltiplos leitores
  • Pode operar com qualquer combinação de leitores: detector, writer e verifier
  • Detector: monitora tags no campo
  • Writer: executa operações de escrita
  • Verifier: verifica integridade dos dados escritos
  • Suporte a GPI para sincronização
  • Logging detalhado com timestamps e métricas

Esta estratégia agora permite executar o teste com 1, 2 ou 3 leitores. Basta informar os hostnames dos leitores desejados; leitores omitidos serão ignorados. Composições suportadas:

  • detector + writer + verifier
  • detector + writer
  • detector + verifier
  • writer + verifier
  • apenas detector
  • apenas writer
  • apenas verifier

Comportamento do Verifier em caso de EPC mismatch

O comportamento do leitor verificador (verifier) ao detectar que o EPC lido nao corresponde ao EPC esperado agora e configuravel, permitindo operar mais rapido quando nao se deseja tentar reescrever a tag.

  • VerifierRewriteOnMismatch: habilita tentativa de reescrita quando ha mismatch (padrao: true). Defina como false para apenas registrar o mismatch sem reescrever.
  • VerifierEpcCompareMode: define como os EPCs sao comparados:
    • "Full": compara o EPC completo
    • "Offset": compara a partir de um deslocamento de caracteres (padrao)
  • VerifierEpcCompareOffset: indice de inicio da comparacao quando em modo Offset (padrao: 13)

Exemplo (OctaneTagWritingTest/config.json):

{
  "VerifierRewriteOnMismatch": false,
  "VerifierEpcCompareMode": "Offset",
  "VerifierEpcCompareOffset": 13
}

Observacoes:

  • Os padroes preservam o comportamento anterior (reescrita habilitada, comparacao por offset em 13).
  • A comparacao por offset reflete a logica previa que desconsiderava campos de cabecalho do EPC.

Parâmetros de Linha de Comando

Parâmetro Descrição
--detector <hostname> Hostname/IP do leitor detector.
--writer <hostname> Hostname/IP do leitor writer.
--verifier <hostname> Hostname/IP do leitor verifier.
--desc <description> Descrição utilizada nos logs do teste.
--sku <sku> SKU de 12 dígitos para codificação.
--header <header> Cabeçalho EPC quando não utiliza SGTIN‑96.
--code <code> Código de item EPC quando não utiliza SGTIN‑96.
--quantity <number> Quantidade de EPCs a gerar.
--detector-power <dbm> Potência de transmissão do detector.
--writer-power <dbm> Potência de transmissão do writer.
--verifier-power <dbm> Potência de transmissão do verifier.
--use-gpi-verification <true/false> Habilita GPI para fase de verificação.
--gpi-trigger-state <true/false> Estado do GPI que inicia a verificação.
`--gpi-port <1 2>`
--gpo-pulse-port <n> Porta GPO utilizada para pulso.
--gpo-static-port <n> Porta GPO utilizada de forma estática.
--detector-antennas "port:power:maxRx:rxSens,..." Configuração das antenas do detector.
--writer-antennas "port:power:maxRx:rxSens,..." Configuração das antenas do writer.
--verifier-antennas "port:power:maxRx:rxSens,..." Configuração das antenas do verifier.
--config <path> Carrega parâmetros de um arquivo JSON.
--interactive Inicia modo de configuração interativo.
--help Mostra mensagem de ajuda.

Dica: informe apenas os parâmetros correspondentes aos leitores presentes. Se um hostname não for fornecido (ou estiver vazio), esse leitor será desconsiderado.

9. CheckBox Strategy (JobStrategy9)

  • Teste específico para funcionalidades CheckBox
  • Validação de SKUs específicos

Configuração e Execução

Linha de Comando

# Execução básica com dois leitores
OctaneTagWritingTest.exe [detector-hostname] [writer-hostname]

# Execução com três leitores (detector, writer, verifier)
OctaneTagWritingTest.exe [detector-hostname] [writer-hostname] [verifier-hostname]

# Modo interativo
OctaneTagWritingTest.exe --interactive

# Ajuda
OctaneTagWritingTest.exe --help

Exemplo rápido: serialização somente com writer

Para cenários de serialização rápida em que apenas um leitor writer está disponível, é possível carregar todas as informações essenciais a partir do config.json e disparar a escrita diretamente com a antena 1. O exemplo abaixo utiliza os campos EpcHeader e EpcPlainItemCode para definir um EPC plano, sem habilitar SGTIN‑96.

  1. Copie OctaneTagWritingTest/config.example.json para OctaneTagWritingTest/config.json e ajuste apenas os campos relevantes:

    {
      "WriterHostname": "writer.local",
      "Sgtin96Enabled": false,
      "EpcHeader": "B6",
      "EpcPlainItemCode": "00000000012345",
      "Quantity": 10,
      "WriterAntennas": {
        "Antennas": [
          {
            "Port": 1,
            "IsEnabled": true,
            "TxPowerInDbm": 27,
            "MaxRxSensitivity": true,
            "RxSensitivityInDbm": -70
          }
        ]
      }
    }

    Os demais campos podem ser removidos ou deixados com valores fictícios; apenas o hostname do writer e a antena utilizada precisam refletir o ambiente real.

  2. Execute o teste informando apenas o writer e o arquivo de configuração:

    dotnet run --project OctaneTagWritingTest -- \
      --writer writer.local \
      --config OctaneTagWritingTest/config.json

    O programa carregará o cabeçalho (EpcHeader) e o código plano (EpcPlainItemCode) do arquivo de configuração e gerará os EPCs sequenciais necessários (Quantity) utilizando exclusivamente a porta 1 do writer.

Exemplo rápido: serialização com três leitores usando SGTIN-96

Para operações que precisam validar cada EPC logo após a escrita, é possível orquestrar os três leitores (detector, writer e verifier) operando com uma antena cada. O detector garante a presença da tag no campo, o writer executa a escrita e o verifier confirma o EPC utilizando a porta GPI 1 para sincronizar o ciclo de verificação. O exemplo abaixo demonstra como carregar o GTIN de origem pelo parâmetro Sgtin96SourceGtin no config.json e reutilizar as antenas padrão (porta 1) em cada leitor.

  1. Copie OctaneTagWritingTest/config.example.json para OctaneTagWritingTest/config.json e ajuste apenas os campos relevantes:

    {
      "DetectorHostname": "detector.local",
      "WriterHostname": "writer.local",
      "VerifierHostname": "verifier.local",
    
      "UseGpiForVerification": true,
      "GpiPortToProcessVerification": 1,
      "GpiTriggerStateToProcessVerification": true,
    
      "Sgtin96Enabled": true,
      "Sgtin96SourceGtin": "01234567890123",
      "Quantity": 48,
    
      "DetectorAntennas": {
        "Antennas": [
          { "Port": 1, "IsEnabled": true, "TxPowerInDbm": 25, "MaxRxSensitivity": true, "RxSensitivityInDbm": -65 }
        ]
      },
      "WriterAntennas": {
        "Antennas": [
          { "Port": 1, "IsEnabled": true, "TxPowerInDbm": 27, "MaxRxSensitivity": true, "RxSensitivityInDbm": -70 }
        ]
      },
      "VerifierAntennas": {
        "Antennas": [
          { "Port": 1, "IsEnabled": true, "TxPowerInDbm": 24, "MaxRxSensitivity": true, "RxSensitivityInDbm": -68 }
        ]
      }
    }

    Ajuste os hostnames e níveis de potência conforme a infraestrutura disponível. O uso de Sgtin96SourceGtin gera a sequência SGTIN-96 automaticamente para a quantidade configurada.

  2. Execute o programa informando os três leitores e o caminho para o arquivo de configuração:

    dotnet run --project OctaneTagWritingTest -- \
      --detector detector.local \
      --writer writer.local \
      --verifier verifier.local \
      --config OctaneTagWritingTest/config.json
  3. Selecione [8] JobStrategy8MultipleReaderEnduranceStrategy quando o menu interativo aparecer. Com UseGpiForVerification habilitado e GpiPortToProcessVerification definido como 1, o verifier aguardará o sinal GPI na porta 1 antes de efetuar a leitura de validação. Enquanto isso, o detector mantém o monitoramento da tag na antena 1, permitindo que o writer serialize rapidamente cada EPC e o verifier confirme o valor escrito.

Exemplo rápido: serialização multi-antena com SGTIN-96 e GPI

Quando há necessidade de serializar tags com o máximo de cobertura física e controle por sensor, é possível operar apenas com o leitor writer utilizando todas as quatro portas de antena e um sensor GPI para iniciar a rotina de leitura/gravação. O exemplo abaixo aproveita o campo Sgtin96SourceGtin para gerar EPCs no formato SGTIN-96 diretamente a partir do config.json.

  1. Copie OctaneTagWritingTest/config.example.json para OctaneTagWritingTest/config.json e ajuste os campos relevantes para o seu ambiente:

    {
      "WriterHostname": "writer.local",
      "UseGpiForVerification": true,
      "GpiPortToProcessVerification": 1,
      "GpiTriggerStateToProcessVerification": true,
      "GpiDebounceInMs": 50,
    
      "Sgtin96Enabled": true,
      "Sgtin96SourceGtin": "01234567890123",
      "Quantity": 96,
    
      "WriterAntennas": {
        "Antennas": [
          { "Port": 1, "IsEnabled": true, "TxPowerInDbm": 27, "MaxRxSensitivity": true,  "RxSensitivityInDbm": -70 },
          { "Port": 2, "IsEnabled": true, "TxPowerInDbm": 27, "MaxRxSensitivity": true,  "RxSensitivityInDbm": -70 },
          { "Port": 3, "IsEnabled": true, "TxPowerInDbm": 27, "MaxRxSensitivity": true,  "RxSensitivityInDbm": -70 },
          { "Port": 4, "IsEnabled": true, "TxPowerInDbm": 27, "MaxRxSensitivity": true,  "RxSensitivityInDbm": -70 }
        ]
      }
    }

    Ajuste o GTIN de origem (Sgtin96SourceGtin), potência de transmissão e sensibilidade de acordo com a infraestrutura instalada. Com UseGpiForVerification habilitado, o programa aguardará o nível configurado na porta GPI 1 antes de iniciar a rodada de escrita/verificação.

  2. Execute o programa informando o hostname do writer e o caminho para o arquivo de configuração:

    dotnet run --project OctaneTagWritingTest -- \
      --writer writer.local \
      --config OctaneTagWritingTest/config.json
  3. No menu interativo exibido ao iniciar a aplicação, escolha a opção [8] JobStrategy8MultipleReaderEnduranceStrategy. Esta estratégia suporta operar apenas com o writer e, com o GPI habilitado, aguarda o acionamento do sensor para disparar o ciclo de leitura/escrita e registrar os EPCs gerados.

    Conecte o sensor ao GPI indicado para que, ao atingir o estado configurado (true no exemplo), o reader inicie o processo de serialização utilizando as quatro antenas em sequência. O desligamento do sensor retorna o sistema ao estado de espera.

Modo Interativo

O aplicativo suporta configuração interativa quando executado sem parâmetros ou com a flag --interactive:

OctaneTagWritingTest.exe -i

Configuração de Leitores

O sistema utiliza ApplicationConfig para gerenciar configurações centralizadas:

  • DetectorHostname: Leitor responsável por detectar tags
  • WriterHostname: Leitor responsável por operações de escrita
  • VerifierHostname: Leitor responsável por verificação

Cada leitor pode ter configurações específicas:

  • Potência de transmissão (TxPowerInDbm)
  • Sensibilidade de recepção (RxSensitivityInDbm)
  • Modo de busca (SearchMode)
  • Sessão (Session)
  • Modo RF (RfMode)

Arquivos de Configuração

  • OctaneTagWritingTest/config.example.json: modelo com valores fictícios utilizado como referência.
  • OctaneTagWritingTest/config.json: cópia local do modelo com hostnames e credenciais reais (não versionado).
  • reader_settings/: diretório criado em tempo de execução contendo ajustes por leitor (não versionado).

Documente qualquer ajuste corporativo adicional no README.md antes de publicar para orientar outros times.

Docker

Build da Imagem

# Build para produção
docker build -t octane-tag-writing-test .

# Build para debug
docker build --build-arg BUILD_CONFIGURATION=Debug -t octane-tag-writing-test .

Execução

# Execução em modo produção (preencha com hostnames internos)
docker run octane-tag-writing-test detector.example.com writer.example.com verifier.example.com

# Execução com dois leitores
docker run octane-tag-writing-test detector.example.com writer.example.com

Substitua os placeholders por hostnames internos resolvíveis. Evite publicar endereços reais na documentação corporativa.

Otimizações Docker

O projeto inclui .dockerignore para otimizar o contexto de build:

  • Artefatos de desenvolvimento (bin/, obj/)
  • Arquivos de controle de versão (.git/, .gitignore)
  • Arquivos de IDE (.vs/, .vscode/, *.user)
  • Arquivos de configuração sensíveis

Sistema de Logging

Cada estratégia de teste gera arquivos de log CSV com métricas relevantes:

Campos Padrão dos Logs

  • Timestamp: Data/hora da operação
  • TID: Tag ID
  • Previous_EPC: EPC anterior
  • New_EPC/Expected_EPC: Novo EPC ou EPC esperado
  • WriteTime_ms: Tempo de escrita em milissegundos
  • VerifyTime_ms: Tempo de verificação em milissegundos
  • Result: Resultado da operação (Success/Failure)
  • RSSI: Força do sinal
  • AntennaPort: Porta da antena utilizada
  • ChipModel: Modelo do chip da tag

Arquivos de Log por Estratégia

  • TestCase0_ReadOnlyLogging_Log-[description].csv
  • TestCase1_Log-SpeedStrategy-[description].csv
  • TestCase3_MultiAntenna_Log-[description].csv
  • TestCase4_VerificationCycle_Log-[description].csv
  • TestCase6_Robustness_Log-[description].csv
  • TestCase7_Log-OptimizedStrategy-[description].csv
  • TestCase8_Log-DualReaderEnduranceStrategy-[description].csv
  • TestCase9_Log-CheckBox-[description].csv

Arquitetura e Padrões

Padrão Strategy

  • IJobStrategy: Interface base para todas as estratégias
  • BaseTestStrategy: Classe base com funcionalidades comuns
  • Estratégias específicas implementam IJobStrategy

Gerenciamento de Configurações

  • ApplicationConfig: Configuração centralizada da aplicação
  • ReaderSettings: Configurações específicas por leitor
  • ReaderSettingsManager: Singleton para gerenciar configurações

Funcionalidades Comuns

  • Conexão e gerenciamento de leitores
  • Configurações padrão otimizadas
  • Relatórios de baixa latência
  • Gerenciamento de listas EPC
  • Logging estruturado em CSV
  • Suporte a cancelamento via CancellationToken

Desenvolvimento

Adicionando Nova Estratégia

  1. Crie uma nova classe na pasta JobStrategies/
  2. Implemente a interface IJobStrategy
  3. Herde de BaseTestStrategy para funcionalidades comuns
  4. Implemente o método RunJob(CancellationToken)
  5. Registre a estratégia no JobManager.cs
public class JobStrategyCustom : BaseTestStrategy
{
    public JobStrategyCustom(string hostname, string logFile, Dictionary<string, ReaderSettings> readerSettings)
        : base(hostname, logFile, readerSettings)
    {
    }

    public override void RunJob(CancellationToken cancellationToken = default)
    {
        // Implementar lógica do teste
    }
}

Configuração de Desenvolvimento

O projeto suporta configuração automática em modo debug:

  • Detecção automática de modo debug
  • Configuração interativa quando sem argumentos
  • Settings pré-configurados para desenvolvimento

Dependências Externas

TagUtils

Projeto auxiliar para utilitários de tags RFID, incluído como dependência do projeto principal.

EpcListGenerator

Utilitário separado para geração de listas EPC, com seu próprio Dockerfile e configurações.

Características Avançadas

Estratégia 8 - Multiple Reader Endurance

Esta estratégia implementa um sistema avançado com três leitores:

// Configuração da estratégia 8
strategies.Add("8", new JobStrategy8MultipleReaderEnduranceStrategy(
    hostnameDetector,    // Leitor detector
    hostnameWriter,      // Leitor writer  
    hostnameVerifier,    // Leitor verifier
    logFile,
    readerSettings,
    applicationConfig    // Configuração centralizada
));

Funcionalidades:

  • Detecção contínua: Leitor detector monitora tags no campo
  • Escrita coordenada: Leitor writer executa operações de escrita
  • Verificação automática: Leitor verifier valida dados escritos
  • Sincronização GPI: Suporte a General Purpose Input para coordenação
  • Retry automático: Re-escrita automática em caso de discrepância
  • Métricas detalhadas: Logging completo de timing e resultados

Suporte a SKU

Estratégias específicas suportam validação por SKU:

strategies.Add("9", new JobStrategy9CheckBox(hostname, logFile, readerSettings, sku));

Troubleshooting

Problemas Comuns

  1. Conexão com leitor falha

    • Verifique conectividade de rede
    • Confirme hostname/IP do leitor
    • Verifique se o leitor está configurado corretamente
  2. Logs não são gerados

    • Verifique permissões de escrita
    • Confirme se o diretório de saída existe
  3. Performance baixa

    • Ajuste configurações de potência e sensibilidade
    • Considere usar estratégias otimizadas (Strategy 7)

Debug

Execute em modo debug para informações detalhadas:

# No Visual Studio
F5 para debug com breakpoints

# Via linha de comando (se compilado em Debug)
OctaneTagWritingTest.exe --debug [argumentos]

Licença

[Especificar Licença]

Contribuição

Para contribuir com o projeto:

  1. Faça fork do repositório
  2. Crie uma branch para sua feature
  3. Implemente e teste suas mudanças
  4. Submeta um pull request

Notas

  • Certifique-se da conectividade adequada do leitor antes de executar testes
  • Revise a documentação individual de cada estratégia para requisitos específicos
  • Verifique os arquivos de log CSV para resultados detalhados dos testes
  • Use o modo interativo para configuração inicial e testes

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Languages