Modo Online

Modo Online

⚠️

Dispositivos que suportam esta função:

DispositivosFirmware
SS 5530220708 ou superior
SS 5530 LITE230307 ou superior
SS 3532 MF W20231018 ou superior
SS 3542 MF W20231018 ou superior
SS 5531 MF W20231018 ou superior
SS 5541 MF W20231018 ou superior
SS 5532 MF W20231018 ou superior
SS 5542 MF W20231018 ou superior
SS 3540 MF BIO231129 ou superior
SS 3540 MF231129 ou superior
SS 3530 MF20240601 ou superior
SS 3530 MF W20240601 ou superior
SS 3430 Bio20240315 ou superior
SS 3430 MF Bio20240315 ou superior
🚨

Importante: Para o funcionamento correto do Modo Online é necessário que o dispositivo esteja configurado com o Feedback no modo "Personalizado".

O Modo Online permite que o dispositivo sempre “pergunte” ao servidor se pode liberar ou negar acesso ao usuário que está tentando acessar determinado ponto de acesso e caso a conexão com o servidor for perdida, operar com lista de usuários liberados (Lista Branca).

O Modo Online possui dois estados: Online e Offline. Cada um terá um fluxo de decisão específico.

Através da integração do modo online algumas funções são possiveis de implementação, tais como:

  • Antipassback global
  • Intertravemento global
  • Acesso manual
  • Antipassback apenas com supervisão
  • Bloqueio de acesso
  • Chamada antecipada
  • Controle de refeição
  • Controle de trânsito
  • Escolta
  • Escolta com dupla passagem
  • Revista aleatória

Keep Alive

O dispositivo tentará uma requisição GET no “Keep alive path”, se a resposta retornada pelo servidor for Código 200 OK, então o dispositivo estará no “Estado Online”, caso a resposta do servidor for algo diferente ou atingir o tempo limite, então o dispositivo entrará no “Estado Offline”. O dispositivo repetirá esse processo com base no “Keep Alive Time”.

KeepAlive

Diagrama de operação do Keep Alive:

KeepAlive2

Estado Online

Quando o dispositivo estiver no estado online, a todos que tentarem acessar o dispositivo, ele postará o evento e aguardará um response do servidor (resposta de autorização) contendo três campos: id, auth e message.

Para credenciais biométricas, o dispositivo verificará se o usuário está cadastrado antes de enviar para o servidor. Se não for, acesso negado.

Para senhas e cartões, mesmo que o usuário não esteja cadastrado, a solicitação de autorização será enviada ao servidor. O servidor responderá à solicitação com um JSON conforme descrito anteriormente. No caso de um TIMEOUT, o dispositivo decidirá com base nos usuários inscritos e o dispositivo mudará para o estado offline. O TIMEOUT é um parâmetro na interface web.

O fluxo abaixo ilustra a explicação.

OnlineState

As requisições POST realizadas pelo dispositivo ao servidor deverão ser respondidas de acordo com o seguinte JSON, contendo as informações:

{ 
    "message": "Seja Bem vindo!", 
    "code": "200", 
    "auth": "true"
}
paramtypedescription
message *StringMensagem que será exibida no display
code *NumberCódigo sempre é 200
auth *StringString true/false corresponde se a porta irá ser acionada ou não.

Estado Offline

Quando o dispositivo estiver no estado offline, para todas as tentativas de acesso ao dispositivo, ele decidirá com base nos usuários cadastrados. No estado offline, todos os usuários têm privilégios VIP, 24 horas por dia, 7 dias por semana.

OfflineState

Servidor de Exemplo

O servidor de exemplo realiza a configuração de duas rotas, sendo a /notifications para receber os eventos e aprovar/negar os acessos e /keepalive para a verificação pelo dispositivo do estado do servidor.

# -*- coding:utf-8 -*-
from flask import Flask,request, jsonify
import json
import ast
import sys, os
import time
 
app = Flask(__name__)
 
@app.route('/notification', methods = ['POST'])
def event_receiver():
    if request.method == 'POST':
        
        
        res = request.data
        data_list = res.split(b"--myboundary\r\n")
        
        if data_list:
            for a_info in data_list:
                if b"Content-Type" in a_info:
                    lines = a_info.split(b"\r\n")
                    a_type = lines[0].split(b": ")[1]
 
                    if a_type == b"image/jpeg":
                        image_data = b"\r\n".join(lines[3:-3])
                    else:
                        text_data = b"\r\n".join(lines[3:-1])
        
 
        evento_str = text_data.decode("utf-8")
        evento_dict = ast.literal_eval(evento_str.replace("--myboundary--", " "))
        json_object = json.dumps(evento_dict, indent = 4) 
        resp_dict = json.loads(json_object)
 
        print(resp_dict)
 
        event_code = resp_dict.get("Events")[0].get('Code')
        print("################## ", event_code, " ##################")
 
        if event_code == "AccessControl":
            event_data = resp_dict.get("Events")[0].get('Data')
            
            card_name = event_data.get('CardName')
            card_no = event_data.get('CardNo')
            card_type = event_data.get('CardType')
            door = event_data.get('Door')
            error_code = event_data.get('ErrorCode')
            method = event_data.get('Method')
            reader_id = event_data.get('ReaderID')
            event_status = event_data.get('Status')
            event_type = event_data.get('Type')
            event_entry = event_data.get('Entry')
            event_utc = event_data.get('UTC')
            user_id = event_data.get('UserID')
            user_type = event_data.get('UserType')
            pwd = event_data.get('DynPWD')
            
            
            print("UserID: ",  user_id)
            print("UserType", user_type)
            print("CardName: ", card_name)
            print("CardNo: ", card_no)
            print("CardType: ", card_type)
            print("Password: ", pwd)
            print("Door: ", door)
            print("ErrorCode: ", error_code)
            print("Method: ", method)
            print("ReaderID: ", reader_id)
            print("Status: ", event_status)
            print("Type: ", event_type)
            print("Entry: ", event_entry)
            print("UTC: ",  event_utc)
            print(49 * "#")
 
            # TESTE DE REGRAS
            time.sleep(1)
            if user_id == 6:
                return jsonify({"message": "Pagamento não realizado! Consulte a secretaria!", "code": "200", "auth": "false"})
            elif card_no in ["EC56D271", "09201802"]:
                return jsonify({"message": "Voce está bloqueado", "code": "200", "auth": "false"})
            elif pwd != None:
                if int(pwd) == 22:
                    return jsonify({"message": "Acesso Liberado", "code": "200", "auth": "true"})
 
        elif event_code == "DoorStatus":
            event_data = resp_dict.get("Events")[0].get('Data')
            
            door_status = event_data.get('Status')
            door_utc = event_data.get('UTC')
            
            print("Door Status: ",  door_status)
            print("UTC", door_utc)
            print(49 * "#")
            return jsonify({"message": "", "code": "200", "auth": "false"})
        
        elif event_code == "BreakIn":
            event_data = resp_dict.get("Events")[0].get('Data')
            
            door_name = event_data.get('Name')
            door_utc = event_data.get('UTC')
            
            print("Door Name: ",  door_name)
            print("UTC", door_utc)
            print(49 * "#")
            return jsonify({"message": "", "code": "200", "auth": "false"})
        
        
    return jsonify({"message": "", "code": "200", "auth": "false"})
 
 
    '''
    
    O retorno deverá ser um JSON, contendo as informações:
    
    "message": "", // Mensagem que será exibida no display
    "code": "200", // Código sempre é 200.
    "auth": "", Boolean, corresponde se a porta irá ser acionada ou não. 
    
    '''
 
@app.route('/keepalive', methods = ['GET'])
def keep_alive():
    return "OK"
 
    '''
    
    Deverá ser retornado qualquer request que contenha código 200.
 
    '''
 
# Server Start
if __name__ == '__main__':
    app.run(host='192.168.3.14', debug=True, port=3000)

Comando para Limpar Eventos em Cache

Caso você possua muitos eventos, tanto no modo servidor de envio de eventos quanto no modo online que não foi feito a confirmação de envio ao servidor e deseja apagar todos os eventos em cache, você pode utilizar o comando abaixo.

Requisição - GET

http://19.168.3.87/cgi-bin/recordUpdater.cgi?action=clear&name=AccessOffline

paramtypedescription
clear *StringComando para Limpar

Exemplo de Retorno - text/plain:

OK
 

Exemplos de Servidor

python Em desenvolvimento...