Skip to content

Latest commit

 

History

History
521 lines (395 loc) · 15.3 KB

File metadata and controls

521 lines (395 loc) · 15.3 KB

Manual Técnico — Protector ISAPI Manager v4.0

Protector Sistemas — Referência técnica para desenvolvedores e integradores Versão 4.0.0 | Março 2026


Sumário

  1. Arquitetura
  2. Stack Tecnológica
  3. Módulos do Sistema
  4. Cliente ISAPI — API Reference
  5. Sistema de Backup v4.0
  6. Sistema de Sessões
  7. Auto-Update
  8. Modelos de Dados
  9. Build e Deploy
  10. Configurações e Diretórios
  11. Parâmetros de Clonagem

1. Arquitetura

O sistema segue uma arquitetura monolítica desktop com separação em camadas:

┌─────────────────────────────────────────────┐
│                   GUI Layer                  │
│          app.py (CustomTkinter)              │
│   Screen*: Clientes, Cadastros, Regras,     │
│   Backup, Auditoria, Eventos, Manutenção,   │
│   Relatórios                                 │
├─────────────────────────────────────────────┤
│               Core Layer                     │
│   isapi_client.py  │ backup.py │ session.py │
│   models.py        │ reports.py│ updater.py │
├─────────────────────────────────────────────┤
│            Communication Layer               │
│         HTTP/HTTPS + Digest Auth             │
│              Protocolo ISAPI                 │
├─────────────────────────────────────────────┤
│          Hikvision Terminals                 │
│     Face Recognition Ultra Series            │
└─────────────────────────────────────────────┘

Princípios:

  • GUI e lógica de negócio no mesmo processo (thread principal para UI, threads auxiliares para operações longas)
  • Cada operação pesada roda em thread separada para não travar a interface
  • Dados persistidos em JSON (clientes/terminais) e ZIP (backups)
  • Sessões persistidas em disco para recover de crash

2. Stack Tecnológica

Componente Tecnologia Versão
Linguagem Python 3.8+
GUI CustomTkinter 5.x
HTTP Client requests 2.x
Auth requests.auth.HTTPDigestAuth
Excel openpyxl 3.x
PDF reportlab 4.x
Empacotamento PyInstaller 6.x
Instalador Inno Setup 6.x
Versionamento packaging 23.x
Testes pytest 7.x

3. Módulos do Sistema

3.1 app.py — Aplicação Principal

Arquivo monolítico que contém toda a GUI e lógica de apresentação. Organizado por classes de tela:

Classe Responsabilidade
ProtectorISAPIManager Classe principal, gerencia navegação e dados globais
ScreenClientes Gestão de clientes e terminais
ScreenCadastros Cadastros de pessoas e biometria
ScreenRegras Regras de acesso
ScreenBackup Backup, restore e sessões
ScreenAuditoria Auditoria de integridade
ScreenEventos Eventos de acesso
ScreenManutencao Manutenção e status
ScreenRelatorios Geração de relatórios

Padrões de uso:

  • Seleção de terminal via self.app.get_terminal_display_list() e self.app.find_terminal_by_display()
  • Operações longas em threading.Thread(target=..., daemon=True)
  • Atualização de UI via self.after(0, callback) (thread-safe)
  • Logs em widgets CTkTextbox com scroll automático

3.2 core/isapi_client.py — Cliente ISAPI

Classe ISAPIClient que encapsula toda comunicação com terminais Hikvision via protocolo ISAPI. Gerencia sessões HTTP com Digest Auth e reconexão automática.

3.3 core/backup.py — Backup Manager

Classes BackupManager e BackupManifest. Cria backups ZIP com integridade SHA256.

3.4 core/session.py — Session Manager

Classes CloneSession, SessionManager, SerialLocker e enum OperationType. Isolamento por sessão com lock por serial.

3.5 core/models.py — Modelos de Dados

Classes GlobalUser, DeviceUser, UserMapping. Identidade global baseada em employeeNo.

3.6 core/reports.py — Relatórios

Geração de relatórios em Excel (openpyxl) e PDF (reportlab).

3.7 core/updater.py — Auto-Update

Classes Updater e UpdateInfo. Consulta GitHub Releases API para verificar atualizações.


4. Cliente ISAPI — API Reference

Inicialização

from core.isapi_client import ISAPIClient
from core.models import Terminal

terminal = Terminal(ip="192.168.1.100", port=80, username="admin", password="senha123")
client = ISAPIClient(terminal, timeout=5)

Informações do Dispositivo

client.get_device_info()      # Serial, modelo, firmware
client.get_device_status()     # Status operacional
client.get_time()              # Hora do sistema
client.get_network_info()      # IP, MAC, gateway, DHCP
client.get_capabilities()      # Features suportadas
client.get_storage_info()      # Uso de memória
client.test_connection()       # Teste de conectividade

Gerenciamento de Usuários

client.get_all_users()                          # Lista todos
client.get_user_count()                         # Contagem
client.search_users(position=0, count=30)       # Busca paginada
client.add_user(user_data)                      # Criar
client.modify_user(user_data)                   # Atualizar
client.delete_user(employee_no)                 # Deletar um
client.delete_all_users(callback=None)          # Deletar todos

Gerenciamento Facial

client.get_face_count()                         # Contagem de faces
client.get_face(employee_no)                    # Download JPEG
client.add_face(employee_no, jpeg_bytes)        # Upload face
client.delete_face(employee_no)                 # Remover face
client.delete_faces(employee_list, callback)    # Batch delete

Clonagem

# Clone completo (users + faces + cards)
client.clone_from(source_client, callback)

# Clone facial 1→1
client.clone_faces_from(source_client, callback)

# Clone facial 1→N (multi-dispositivo)
client.clone_faces_multi(source_client, callback)

Controle de Porta

client.get_door_status(door_id=1)
client.remote_door_open(door_id=1)       # Abrir
client.remote_door_close(door_id=1)      # Fechar
client.remote_door_always_open(door_id=1)  # Manter aberta
client.remote_door_always_close(door_id=1) # Manter fechada
client.remote_door_normal(door_id=1)       # Modo normal

Regras de Acesso

client.get_all_rules(max_templates=8, max_weeks=8, max_holidays=8)
client.apply_rules(rules, callback)
client.get_schedule_template(template_id)
client.set_schedule_template(template_id, data)
client.get_week_plan(plan_id)
client.set_week_plan(plan_id, data)
client.get_holiday_group(group_id)
client.set_holiday_group(group_id, data)

Eventos

client.get_event_count()
client.get_recent_events(count=100)
client.search_events(start_time, end_time, position=0, count=30)
client.get_all_events(start_time, end_time, max_events=500)
client.collect_events(start_time)

Configuração

client.export_config()                    # Exportar config binária
client.import_config(data)                # Importar config
client.set_time(time_str, timezone)       # Ajustar hora
client.set_ntp(server, timezone, port)    # Configurar NTP
client.reboot()                           # Reiniciar
client.factory_reset(keep_network=False)  # Reset de fábrica

5. Sistema de Backup v4.0

Estrutura do ZIP

backup_20260301_143000_SER12345_SID-XXXX.zip
├── users.json          # Array de UserInfo
├── cards.json          # Array de CardInfo
├── faces/
│   ├── EMP001.jpg      # JPEG por employeeNo
│   ├── EMP002.jpg
│   └── ...
├── config.bin          # Configuração binária do dispositivo
└── manifest.json       # Metadados + hash SHA256

Manifest

{
  "version": "4.0",
  "device_serial": "DS-K1T344MX-E120241025V041300ENFU5491529",
  "model": "DS-K1T344MX-E",
  "firmware": "V4.1.300",
  "user_count": 150,
  "photo_count": 148,
  "card_count": 50,
  "config_size": 124492,
  "session_id": "SID-3A20-C5EE-44A1",
  "timestamp": "2026-03-01T14:30:00",
  "backup_hash": "a3f2b1c4d5e6f789",
  "created_by": "Protector ISAPI Manager v4.0"
}

API de Backup

from core.backup import BackupManager

bm = BackupManager(backup_dir="Backups")

# Criar backup
result = bm.create_backup(client, session, callback,
                          include_faces=True, include_config=True)
# result: {ok, file, size, manifest, error}

# Restaurar
result = bm.restore_backup(zip_path, target_client, session, callback,
                           skip_config=False)
# result: {ok, users_restored, faces_restored, cards_restored, config_restored, error}

# Validar integridade
result = BackupManager.validate_backup(zip_path)
# result: {valid, manifest, error}

# Listar backups
backups = bm.list_backups(serial=None)

6. Sistema de Sessões

Conceito

Toda operação destrutiva ou de longa duração é envolvida em uma sessão com ID único. Isso garante rastreabilidade, impede operações concorrentes e permite recover de crash.

Tipos de Operação

Tipo Uso
CLONE_NATIVE Clonagem entre terminais da mesma marca
CLONE_CROSS_BRAND Clonagem cross-brand (futuro)
PURGE Limpeza completa do dispositivo
RESTORE Restauração de backup
BACKUP Operação de backup standalone

Ciclo de Vida

PENDING → RUNNING → COMPLETED
                  → FAILED
                  → CANCELLED

API de Sessão

from core.session import SessionManager, OperationType

sm = SessionManager(sessions_dir="sessions")

# Criar sessão
session = sm.create_session(
    operation_type=OperationType.BACKUP,
    dest_serial="SER12345",
    dest_ip="192.168.1.100"
)

# Operar
session.start()
session.mark_employee_done("EMP001")
session.mark_employee_done("EMP002")
session.complete()

# Ou em caso de erro
session.fail("Timeout na conexão")

Serial Locking

from core.session import SerialLocker

locker = SerialLocker()
locker.acquire("SER12345", "SID-XXXX-XXXX-XXXX")  # Adquire lock
locker.is_locked("SER12345")  # True
locker.release("SER12345")    # Libera

O lock impede que duas operações rodem simultaneamente no mesmo terminal. É thread-safe e baseado em threading.Lock.


7. Auto-Update

Fluxo

App inicia
  → Thread background (3s delay)
    → GET https://api.github.com/repos/{owner}/{repo}/releases/latest
    → Compara versão remota vs local (packaging.version)
    → Se mais nova: callback na UI thread
      → Diálogo com release notes
      → Download com progress bar
      → Executa installer /SILENT
      → App fecha

API do Updater

from core.updater import Updater, check_update_async

updater = Updater(
    current_version="4.0.0",
    github_owner="ProtectorAnalytics",
    github_repo="protector-isapi-manager",
    token=None  # Opcional para repos privados
)

# Check síncrono
info = updater.check_for_update()
if info:
    path = updater.download_update(info, progress_callback)
    updater.install_update(path)

# Check assíncrono (recomendado)
check_update_async("4.0.0", "ProtectorAnalytics",
                   "protector-isapi-manager", callback=on_update)

8. Modelos de Dados

Terminal

Terminal(
    ip="192.168.1.100",
    port=80,
    username="admin",
    password="senha123",
    name="Recepção",
    model="DS-K1T344MX-E",
    serial="DS-K1T344MX-E120241025V041300ENFU5491529",
    firmware="V4.1.300"
)

Client

Client(
    name="Empresa XYZ",
    terminals=[Terminal(...), Terminal(...)]
)

Dados persistidos

  • dados.json — Clientes e terminais (estrutura principal)
  • sessions/*.json — Sessões de operação
  • backups/{serial}/*.zip — Backups completos
  • events/*.json — Eventos coletados

9. Build e Deploy

Pipeline de Build

# Build completo com instalador
python build_release.py --clean --installer

# Build + GitHub Release
python build_release.py --clean --installer --github

# Apenas instalador (se .exe já existe)
python build_release.py --skip-build --installer

Etapas do Pipeline

  1. Clean — Remove build/ e dist/
  2. build_info.py — Atualiza timestamp de build
  3. file_version_info.txt — Gera metadados de versão para o .exe
  4. PyInstaller — Gera dist/Protector_ISAPI_Manager.exe (~32MB)
  5. Inno Setup — Gera dist/installer/Protector_ISAPI_Manager_v4.0.0_Setup.exe (~33MB)
  6. GitHub Release — Cria release e faz upload (via gh CLI)

Versionamento

O version.py é a fonte única de verdade:

VERSION = "4.0.0"
VERSION_STATUS = "stable"    # stable | beta | rcN
CHANNEL = "release"          # release | dev
GITHUB_OWNER = "ProtectorAnalytics"
GITHUB_REPO = "protector-isapi-manager"

Para lançar nova versão: altere VERSION em version.py e rode o pipeline.


10. Configurações e Diretórios

Diretórios de Dados

Diretório Conteúdo Gitignored
backups/ Backups ZIP por serial Sim
sessions/ Sessões JSON Sim
events/ Eventos coletados Sim
assets/ Ícones e logos Não
docs/ Documentação Não
tests/ Testes unitários Não
scripts/ Scripts auxiliares .bat Não

Parâmetros de Rede

Parâmetro Valor Padrão
Timeout de conexão 5 segundos
Porta HTTP 80
Auth Digest (HTTPDigestAuth)
NTP Server a.ntp.br
NTP Port 123
NTP Interval 60 segundos

11. Parâmetros de Clonagem

Parâmetros calibrados para estabilidade em operações de clonagem facial:

Parâmetro Valor Descrição
COOLDOWN_MIN 2.0s Intervalo mínimo entre envios
COOLDOWN_START 2.5s Cooldown inicial
COOLDOWN_MAX 20.0s Cooldown máximo (backoff)
BACKOFF_MULT 2.0x Multiplicador de backoff
RECOVER_AFTER 5 Envios OK para reduzir cooldown
RECOVER_FACTOR 0.6 Fator de redução do cooldown
REAUTH_EVERY 25 Re-auth preventiva a cada N envios
HEALTH_EVERY 20 Health check a cada N envios
AUTH_RETRY_MAX 2 Tentativas de re-auth
BUSY_MAX_RETRIES 3 Retries quando terminal ocupado

O backoff adaptativo funciona assim: em caso de erro HTTP ou timeout, o cooldown dobra (BACKOFF_MULT). Após RECOVER_AFTER envios bem-sucedidos, o cooldown reduz em 40% (RECOVER_FACTOR). Isso garante que o terminal não fique sobrecarregado.


Protector Sistemas © 2026 — Todos os direitos reservados