# Ocorrências

> Condições vigiadas da coisa sob teste, escritas como expressão JavaScript sobre os canais do modelo e julgadas durante uma execução ou sempre.

Uma **ocorrência** registra que a coisa sob teste fez algo digno de nota. Onde um alarme vigia a
planta e o equipamento, uma ocorrência pertence ao procedimento: as arestas dela ficam com a
execução que as observou e também entram na linha do tempo persistente de Ocorrências da página
Eventos. A condição dela é uma expressão JavaScript sobre os canais do modelo, com antirrepique nas
duas arestas e condicionada pela qualidade do que ela lê. As ocorrências vivem em Process > Modelos >
modelo > Preparação > **Ocorrências** e exigem a permissão **Editar receitas e avaliações**.

## A pasta Ocorrências {#the-occurrences-folder}

Selecionar a linha **Ocorrências** abre a página da pasta ("Condições observadas da coisa sob ensaio.
Toda aresta fica com a execução dela quando cabe e também entra no histórico permanente de
Ocorrências.") com um cartão por ocorrência, por nome; clicar num cartão o abre, e o X o remove. Sem
nenhuma, a página diz "Nenhuma ocorrência ainda. Adicione uma."

| Comando | O que faz | Fica cinza quando (situação) | Não é desenhado quando (papel) |
| --- | --- | --- | --- |
| **Ocorrência** (barra de detalhe, com a pasta selecionada; clique direito **Adicionar ocorrência**) | Acrescenta `Ocorrência <n>`: severidade Alerta, armada durante procedimentos, habilitada, sem mensagem, condição vazia. A linha entra no grupo dela, destacada e rolada até ficar à vista ali; o cartão dela a abre. | Alguma unidade tem uma execução, ou o runtime está parado. | Sem Editar receitas e avaliações. |

## A página da ocorrência {#the-occurrences-page}

O cabeçalho carrega o nome, uma pílula com a severidade (na cor da própria severidade) e uma pílula
**Desabilitada** quando a ocorrência está desligada. Dois tipos de aviso podem ficar sob ele:

- Uma nota de cautela quando a condição salva não valida (o rascunho continua salvo; a nota diz o
  que está errado, veja abaixo).
- Um aviso **Avaliação indisponível** por unidade em que a condição ao vivo não pôde ser avaliada,
  como "`<unit>`: `<error>`". O diagnóstico de uma unidade é escrito uma vez por erro inalterado e
  limpo quando a avaliação volta a dar certo.

### Identidade e comportamento {#identity--behavior}

| Campo | O que é | Valores / padrão | Efeito |
| --- | --- | --- | --- |
| **Nome** | O nome da ocorrência: a linha da árvore, o rótulo do evento no arquivo da execução, na linha do tempo de Eventos e nos relatórios. | Texto livre; `Ocorrência <n>` na criação. | Renomeia a linha e o que a lista de um procedimento chama assim. |
| **Severidade** | O peso de uma ativação. O seletor mostra cada opção na tinta que a pílula dela vai carregar. | **Informação**, **Aviso** (padrão), **Crítica**. | Colore a pílula e o episódio onde quer que ele seja listado. Durante uma execução, uma ativação de uma ocorrência Aviso ou Crítica também pede uma notificação do sistema operacional enquanto a aplicação está escondida ou minimizada; Informação fica na janela. |
| **Armada** | Quando a condição é julgada. | **Durante um procedimento** (padrão): apenas enquanto uma execução de um procedimento que a arma está ativa, sobre as linhas gravadas. **Sempre**: também fora de execução, por um vigia de fundo que lê os vínculos da unidade ao vivo. | Uma ocorrência do modo Sempre não precisa de procedimento para armá-la; uma do modo Durante um procedimento só é julgada pelos procedimentos que a marcam. |
| **Atraso para ligar (ms)** | Quanto tempo a condição precisa ficar verdadeira antes de **Ativada** ser confirmada, na resolução das amostras. | Um número de milissegundos; 0 por padrão. O campo não aceita número negativo: a entrada é recusada, a nota diz isso embaixo do campo, e o valor anterior volta. | Faz o antirrepique da aresta de subida. |
| **Atraso para desligar (ms)** | Quanto tempo a condição precisa ficar falsa antes de **Encerrada** ser confirmada. | O mesmo; 0 por padrão. | Faz o antirrepique da aresta de descida. |
| **Habilitada** | Se a ocorrência arma. | Ligada por padrão. | Uma ocorrência desabilitada nunca arma, dentro ou fora de execução, e nunca bloqueia o Iniciar. |
| **Mensagem** | O texto gravado e anunciado com uma ativação. | Texto livre; vazio por padrão. | Viaja com toda aresta para o arquivo da execução e para o diário. |

### Condição {#condition}

"Uma única expressão JavaScript que devolve um booleano." O cartão tem um editor de código, a lista das
referências que você pode usar ("Referências de canal disponíveis: Channels.Ch_1,
Channels.Outlet_temperature, …") e o lembrete "Durante uma execução a condição lê as colunas
registradas do datalog; o observador Sempre lê os vínculos da unidade ao vivo. Erros de sintaxe,
referências faltando e falhas de avaliação em tempo de execução são mostrados aqui, sem serem
tratados como falso nem como perda de sinal."

Um canal é referenciado como `Channels.<identifier>`, onde o identificador é o nome do canal
higienizado: letras e dígitos sobrevivem, todo outro caractere vira `_`, e um nome que começa com
dígito ganha um `_` na frente. `Channels` guarda apenas os canais do modelo e nada mais, então um
canal chamado `Math`, `isNaN` ou `true` continua sendo um nome de canal válido e não esconde
nenhuma global do JavaScript. Um `NaN` presente e bom é dado que você pode testar com
`isNaN(Channels.Pv)`. Exemplos: `Channels.Outlet_temperature > 80`, `Channels.Door_open &&
Channels.Heater_on`.

O rascunho é validado enquanto você digita, contra valores de amostra do tipo de cada canal, e a
nota de cautela sob o cabeçalho diz o que falha:

| Nota | Significado |
| --- | --- |
| "Erro de sintaxe: …" | A expressão não é analisada. |
| "A referência de canal 'Channels.X' não existe neste modelo." | Uma referência não nomeia canal nenhum. |
| "Mais de um canal mapeia para 'Channels.X'." | Dois nomes de canal se higienizam no mesmo identificador; renomeie um na grade de Canais. |
| "A condição precisa devolver um booleano, mas devolveu `<type>`." | A expressão rende algo que não é verdadeiro nem falso. |
| "Erro de avaliação: …" | A expressão lança uma exceção. |

Uma condição inválida ainda é salva como rascunho. Ela tem consequências em outros lugares: uma
ocorrência habilitada que falha na validação e é armada por um procedimento (marcada nele, ou
armada no modo Sempre) bloqueia o Iniciar daquele procedimento, e a página do procedimento mostra
"A ocorrência '`<name>`' é inválida: …"; uma ocorrência inválida do modo Sempre não inicia o vigia
de fora de execução dela e deixa um diagnóstico visível aqui, em vez de repeti-lo a cada leitura.

Cada avaliação corre num motor restrito (um limite de 500 ms, um número limitado de instruções e
memória limitada), então uma expressão desgovernada falha na avaliação dela, não na estação.

## Como uma ocorrência é julgada {#how-an-occurrence-is-judged}

Durante uma execução, a condição é julgada sobre as linhas que o datalog grava, então um canal que
o datalog do procedimento não grava fica indisponível para ela. Um procedimento que arma uma
ocorrência sobre um canal assim, ou que arma uma e não grava nada, é recusado na página dele e no
Iniciar: a ocorrência nunca julgaria, e a nota de cautela a nomeia. Fora de execução, uma ocorrência
do modo Sempre é julgada por um vigia que lê os vínculos da unidade ao vivo. Qualquer um dos dois
juízes segura o último estado confirmado enquanto algum canal referenciado está indisponível: só um
valor faltando ou uma qualidade ruim suspende o julgamento, e um valor presente e bom (um `NaN`
inclusive) é dado avaliável. O juiz grava quatro transições: **Ativada** (depois do atraso para ligar),
**Encerrada** (depois do atraso para desligar), **Indisponível** (um canal referenciado perdeu o
sinal dele) e **Restaurada** (todo canal referenciado voltou; a condição é julgada de novo e o
atraso aplicável recomeça).

Durante uma execução, toda transição é escrita primeiro no arquivo da execução e depois copiada,
com o contexto da execução, para o diário durável na página [Eventos](events-occurrences); fora de
execução, o vigia escreve apenas no diário. Iniciar uma execução descarta o juiz de fora de execução
da unidade, e sair da execução cria um novo, então nenhuma ativação atravessa uma fronteira não
observada. Edições no nome, na mensagem ou na severidade afetam apenas as arestas posteriores;
edições na condição, nos atrasos, no modo de armar ou no estado de habilitação começam uma
observação nova.

Os episódios (da ativação até a normalização, com qualquer intervalo de perda de sinal contado à
parte) são derivados dessas arestas onde quer que a aplicação os mostre: o cartão Ocorrências de um
painel, a página Eventos, os Históricos e os relatórios. O tempo ativo de um episódio é exatamente o
intervalo entre as duas arestas persistidas, então ele exclui o atraso para ligar e inclui o atraso para
desligar: o relógio começa quando a condição já se manteve pelo atraso para ligar, e só para quando a
normalização é escrita, depois de o atraso para desligar correr. É esse o número que um relatório
entrega a um terceiro.

## Onde uma ocorrência é usada {#where-an-occurrence-is-used}

A página de um procedimento carrega o cartão **Ocorrências armadas durante este procedimento**, com
uma pílula "`<n>` armadas" e uma caixa de seleção por ocorrência do modelo, por nome. Marcar uma a
arma durante as execuções daquele procedimento; uma ocorrência armada no modo **Sempre** vigia de
qualquer jeito e não precisa de marcação. Sem nenhuma ocorrência no modelo, o cartão diz "Nenhuma
ocorrência neste modelo ainda. Acrescente algumas em Ocorrências do modelo." Veja
[Procedimentos](process-procedures).

Renomear um canal reescreve as referências `Channels.<identifier>` daquele canal em toda condição do
modelo; isso não toca em textos, comentários nem numa propriedade de mesmo nome em outro objeto.

## Remover ocorrência {#remove-occurrence}

**Remover ocorrência** fica no grupo de perigo da barra de detalhe com a ocorrência selecionada, no
menu de clique direito dela, e como o X no cartão da página da pasta. Ele pergunta antes ("Excluir
ocorrência", "Isso remove a ocorrência do modelo.") e desarma a ocorrência de todo procedimento que
a marcava. Ele exige Editar receitas e avaliações e fica cinza sob a trava de engenharia e o runtime
parado.

## O que uma ocorrência não faz {#what-an-occurrence-does-not-do}

- Ela não é um alarme: não é reconhecida, não tem prioridade e não vigia tags. Os alarmes da planta
  estão na página [Logic](logic-alarms).
- Ela não dispara nada. Uma ativação é gravada e anunciada; nenhuma ação, etiqueta ou relatório está
  presa a ela.
- Ela não consegue ler nada além dos canais do modelo: nenhuma tag, nenhuma variável, nenhum outro
  modelo.
- Ela não é julgada de forma diferente por unidade: uma condição serve toda unidade, sobre os
  vínculos ou as linhas gravadas daquela unidade.
