> For the complete documentation index, see [llms.txt](https://portal-integracao.intelbras.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portal-integracao.intelbras.com.br/linha-de-faciais/modo-online/modo-online-2.0.md).

# Modo Online 2.0

<details>

<summary>Lista de Dispositivos com Suporte a Função</summary>

| Dispositivos    | Firmware             |
| --------------- | -------------------- |
| SS 3531 MF Lite | 20250625 ou superior |
| SS 3542 MF LITE | 20250625 ou superior |
| SS 3532 MF      | 20250625 ou superior |
| SS 3532 MF      | 20250625 ou superior |
| SS 3532 MF W    | 20250625 ou superior |
| SS 3542 MF W    | 20250625 ou superior |
| SS 5531 MF W    | 20250625 ou superior |
| SS 5531 MF EX   | 20250625 ou superior |
| SS 5541 MF W    | 20250625 ou superior |
| SS 5532 MF W    | 20250625 ou superior |
| SS 5542 MF W    | 20250625 ou superior |

</details>

O Modo Online 2.0 contém a mesma lógica de operação do [Modo Online 1.0](/linha-de-faciais/modo-online/modo-online-1.0.md), onde irá requisitar ao servidor a permissão de acesso ao usuário.

#### Diferenciais

Os principais diferenciais do Modo Online 2.0 para o Modo Online são:

* Separação do servidor de autenticação do servidor de envio de eventos
* Formato do Content-Type em `application/json` nativo, com possibilidade de retorno para o uso de text/plain
* Feedback customizável: com a possibilidade de apresentar um feedback customizável por usuário (áudio e imagem)
* Tempo de permanência de porta aberta: possibilidade de determinar um tempo diferente do tempo padrão do dispositivo para manter a porta aberta
* Seleção de porta: indicar qual porta deseja ser aberta após a autorização da autenticação
* Envio da imagem do evento de requisição de acesso em formato base64, junto do corpo do evento, através do objeto "ImageEncode"
* Possibilidade de configurar qual(is) perfil(is) de acesso irão requisitar acesso ao servidor
* Suporte a HTTPS

#### Keep Alive

Da mesma forma que é efetuado no Modo Online, o dispositivo tentará uma requisição GET no “Keep alive path”, e a resposta retornada pelo servidor deve ser o código 200 OK. Com isso, 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”.

Diagrama de operação do Keep Alive:

![KeepAlive2](https://i.imgur.com/B21ta2A.png)

#### 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 obrigatórios: `id`, `auth` e `message`.

No Modo Online 2.0, além dos campos obrigatórios para liberação ou não do acesso ao usuário é possível encaminhar os campos: `image`, `audio`, `feedback` e `doorTime`.

{% hint style="warning" %}
Importante: Certifique-se de responder com os cabeçalhos de Content-Type e Content-Lenght corretamente.
{% endhint %}

As requisições POST enviadas do dispositivo para o servidor deverão ser respondidas de acordo com o seguinte JSON, contendo as informações:

```json
{ 
    "message": "Seja Bem vindo!", 
    "code": "200", 
    "auth": "true", 
    "image": "persona.jpg",
    "audio": "bem_vindo.mp3",
    "feedback": "15",
    "doorTime": {"channel": 0, "Time": 10}
}
```

<table><thead><tr><th>param</th><th>type</th><th width="451.111083984375">description</th></tr></thead><tbody><tr><td><code>message</code> *</td><td>String</td><td>Mensagem que será exibida no display com até 64 caracteres. Máximo 42 caracteres na primeira linha</td></tr><tr><td><code>code</code> *</td><td>Number</td><td>Código sempre é 200</td></tr><tr><td><code>auth</code> *</td><td>String</td><td>String true/false corresponde se a porta irá ser acionada ou não - Acesso Liberado ou Negado.</td></tr><tr><td><code>image</code></td><td>String</td><td>Opcional: Nome do arquivo previamente enviado ao dispositivo.</td></tr><tr><td><code>audio</code></td><td>String</td><td>Opcional: Nome do arquivo previamente enviado ao dispositivo.</td></tr><tr><td><code>feedback</code></td><td>Integer</td><td>Opcional: Tempo em segundos de permanência da imagem de feedback na tela do dispositivo.</td></tr><tr><td><code>doorTime</code></td><td>Integer</td><td>Opcional: Campo <code>channel</code> correspondente a posição da porta para acionamento, sendo 0 a porta principal e 1 a porta secundária. O campo <code>Time</code> é o valor inteiro que corresponde aos segundos que a porta permanecerá aberta.</td></tr></tbody></table>

Caso não seja usado os campos opcionais, o dispositivo irá usar a sua configuração padrão para o acesso.

Os arquivos de mídia para os objetos `image` e `audio` deverão ser carregados no dispositivo via interface web ou comando de API. Para maiores detalhes, verifique a página **Enviar Mídias** .

{% hint style="warning" %}
Importante: Para credenciais biométricas (face e digital), é mandatório o cadastro prévio do usuário no dispositivo antes do envio ao servidor, pois dessa forma, será feito a validação da biometria baseado nos algoritmos do dispositivo. Caso as credenciais biométricas não estejam cadastradas para o usuário, seu acesso será 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.
{% endhint %}

O fluxo abaixo ilustra a explicação.

![OnlineState](https://i.imgur.com/3g63rwi.png)

#### Estado Offline

Quando o dispositivo estiver no estado offline, todas as tentativas de acesso serão validadas pelo dispositivo, conforme as regras e configurações realizadas para o usuário cadastro.

![OfflineState](https://i.imgur.com/oEHus7L.png)

### Servidor de Exemplo

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

{% tabs %}
{% tab title="Python" %}

```
from flask import Flask, request, jsonify
import json

app = Flask(__name__)

@app.route('/auth', methods=['POST'])
def receber_evento():
    json_string = request.get_json('Events')
    
        
    if json_string:
        try:
            # Converte de string para dicionário (JSON)
            dados = request.get_json(force=True) if request.is_json else eval(json_string)
            
            return jsonify({"message": "Bem-Vindo!", "code": "200", "auth": "true", "doorTime": {"channel": 2, "Time": 8}}) # channel:0 - door 1, 1: door 2
            #return jsonify({"message": "Bem-Vindo!", "code": "200", "auth": "true", "image": "imagem1.png", "audio": "test.mp3", "feedback": 15, "doorTime": {"channel": 1, "Time": 15}}) -- resposta completa
            
        except Exception as e:
            print("Erro ao processar JSON:", e)
            return jsonify({"erro": "JSON inválido", "detalhe": str(e)}), 400
    else:
        return jsonify({"erro": "Campo 'info' não encontrado"}), 400


@app.route('/notification', methods=['POST'])
def post_events():
    # Pega o JSON do corpo
    data = request.get_json(silent=True)  # evita exception se o conteúdo não for JSON

    if not data:
        print("Corpo não é JSON ou veio vazio.")
        return 'Bad Request: esperado JSON', 400

    # Se quiser um campo específico (ex.: 'Events')
    events = data.get('Events')

    # Pretty print do JSON completo
    #print("JSON recebido (com identação):")
    #print(json.dumps(data, indent=2, ensure_ascii=False))

    # Ou apenas do campo 'Events'
    if events is not None:
        print("\nCampo 'Events':")
        print(json.dumps(events, indent=2, ensure_ascii=False))

    return 'OK', 200



@app.route('/keepalive', methods = ['GET'])
def keep_alive():
    return "OK"

    '''
    Deverá ser retornado qualquer request que contenha código 200.
    '''


if __name__ == '__main__':
    app.run(host='10.100.78.73', debug=True, port=3000)
```

{% endtab %}

{% tab title="Node" %}

{% endtab %}
{% endtabs %}

### Comando para Limpar Eventos em Cache - Modo Online 2.0

Caso você possua muitos eventos, tanto no modo servidor de envio de eventos 2.0 quanto no modo online 2.0, em que não foi feita a confirmação de envio ao servidor, e deseje 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=AccessOffline2`

| param      | type   | description         |
| ---------- | ------ | ------------------- |
| `clear` \* | String | Comando para Limpar |

#### Exemplo de Retorno - *text/plain*:

```sh
OK

```

####


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://portal-integracao.intelbras.com.br/linha-de-faciais/modo-online/modo-online-2.0.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
