# Ocurrencias

> La cronología persistente de todos los flancos de ocurrencia, observados por el juez de una corrida o por el observador Always fuera de corrida, con la condición congelada que hay detrás de cada uno.

La pestaña Ocurrencias de [Eventos](events) (`/events?view=occurrences`) es la cronología persistente
de lo que hicieron las cosas bajo prueba: una fila por **flanco de ocurrencia**, ya sea que lo haya
observado el juez de una corrida o el observador **Siempre** fuera de corrida. Verla exige **Ver los
eventos**; exportar exige **Exportar/importar históricos**. Las ocurrencias se definen por modelo en
[Process > Preparación > Ocurrencias](process-occurrences); esta pestaña lee su histórico y no cambia nada.

Sigue la conducta compartida de las tres cronologías que describe
[Eventos](events#how-the-three-timelines-behave): 500 filas por página con un paginador debajo, un
periodo, una búsqueda retardada, actualización en vivo, un panel de detalle y exportación CSV y
JSON de todo el periodo.

## Qué es una fila {#what-one-row-is}

Una ocurrencia es una condición booleana sobre los canales de un modelo, con un retardo de activación
y un retardo de desactivación. Una fila es una de las cuatro transiciones de una **sesión de
observación**:

| Transición | Significado |
| --- | --- |
| Activada | La condición subió y se mantuvo durante el retardo de activación. |
| Restablecida | La condición cayó y se mantuvo durante el retardo de desactivación. |
| No disponible | Uno o varios canales a los que la condición se refiere dejaron de entregar valor. El juez mantiene su última condición confirmada y nunca fabrica un restablecimiento. |
| Restaurada | Todos los canales referenciados vuelven a entregar; la condición se evalúa de nuevo y su retardo vuelve a empezar. |

Cada fila dice además en qué **ámbito** se observó y por qué empezó su sesión:

| Campo | Valores | Significado |
| --- | --- | --- |
| Ámbito | **Corrida**, **Fuera de corrida** | Corrida: el juez propio de una corrida, armado por el procedimiento; el flanco se escribe además en el archivo de esa corrida. Fuera de corrida: el observador Always que lee los vínculos de la unidad entre corridas. |
| Motivo | **Corrida iniciada**, **Corrida reanudada**, **Vigilancia iniciada**, **Observación fuera de corrida reanudada**, **Definición modificada** | Por qué empezó una nueva sesión de observación: una corrida arrancó; una corrida se reanudó tras reiniciarse la aplicación; el observador Always arrancó para esta ocurrencia y esta unidad; la unidad volvió a la observación fuera de corrida después de una corrida; o se editaron la condición, los retardos, los canales referenciados, el estado de activación o el modo de armado. |

Una sesión nueva empieza de cero: no se arrastra ninguna condición, disponibilidad ni estado de
antirrebote a través de un hueco sin observación, así que una condición que ya era cierta puede
producir otra **Activada** cuando arranca una corrida o cuando la aplicación regresa, y en esta
cronología no hay fila sintética de "sesión iniciada". El archivo de la propia corrida graba el
límite de la sesión aunque no siga ninguna transición; Históricos y los reportes lo usan para
clasificar como Interrumpida una activación abierta más antigua. Esa marca se queda fuera de esta
cronología y no genera ninguna notificación. Las ediciones que solo afectan a lo mostrado (nombre,
mensaje, gravedad) conservan la sesión y solo cambian las instantáneas posteriores.

## Búsqueda y filtro {#search-and-filter}

| Control | Valores | Qué hace |
| --- | --- | --- |
| Búsqueda | Marcador de posición "Buscar por nombre, mensaje, modelo, unidad o procedimiento" | Comparación de tipo "contiene" con el nombre de la ocurrencia, su mensaje, el nombre del modelo, el de la unidad y el del procedimiento, tal como quedaron en la instantánea del momento. |
| Gravedad | **Todas las gravedades** (predeterminado), **Crítica**, **Advertencia**, **Información** | Conserva solo las transiciones de ocurrencias que llevaban esa gravedad cuando ocurrieron. |
| Actualizar | | Vuelve a leer el diario; información emergente "Actualizar las ocurrencias". |
| Exportar | **Exportar como CSV…**, **Exportar como JSON…** | Escribe toda transición que alcanzan la búsqueda, la gravedad y el periodo, página tras página, y no solo las filas listadas en ese momento. Se dibuja solo con **Exportar/importar históricos**; se atenúa mientras la lista está vacía. |

## Las filas {#the-rows}

| Parte de la fila | Contenido |
| --- | --- |
| Hora | Fecha y hora en que el juez observó el flanco (para una corrida, la marca de tiempo de la propia muestra juzgada). |
| Punto | El tono de la gravedad: crítico para Crítica, precaución para Advertencia, neutro para Información. |
| Nombre | El nombre que tenía la ocurrencia en ese momento. |
| Resumen | "Transición · obs. N (Motivo) · Modelo / Unidad · contexto", donde N es el orden del flanco dentro de su sesión y el contexto es "Corrida · " seguido del nombre del procedimiento (o solo "Corrida" cuando no se grabó ningún nombre de procedimiento) o "Fuera de corrida". Ejemplo: "Activada · obs. 1 (Corrida iniciada) · Furnace / Línea 2 · Corrida · Cocción 180". |
| Nivel | La palabra de la gravedad. |

El mensaje que lleva una fila es el mensaje propio de la ocurrencia para **Activada** y
**Restablecida** (vacío cuando la definición no tiene ninguno, mostrado como "No se capturó ningún
mensaje." en el panel), y para los flancos de disponibilidad "Señal no disponible:" o "Señal
restaurada:" seguido de los nombres de los canales afectados, separados por comas.

## El panel de detalle {#the-detail-panel}

Al seleccionar una fila se abre el panel con la insignia de la gravedad y el nombre, la marca de
tiempo completa, la línea de resumen, el mensaje y cuatro tarjetas:

| Tarjeta | Campo | Contenido |
| --- | --- | --- |
| EVENTO | Nivel | La gravedad. |
| EVENTO | ID del evento | La identidad de este flanco en el diario. Para una observación de corrida es el mismo identificador que guarda el archivo de la corrida. |
| INSTANTÁNEA DE LA OCURRENCIA | Transición | Activada, Restablecida, No disponible o Restaurada. |
| INSTANTÁNEA DE LA OCURRENCIA | Modelo | El nombre que tenía el modelo en ese momento. |
| INSTANTÁNEA DE LA OCURRENCIA | Unidad | El nombre que tenía la unidad en ese momento. |
| INSTANTÁNEA DE LA OCURRENCIA | Alcance | Corrida o Fuera de corrida. |
| INSTANTÁNEA DE LA OCURRENCIA | Procedimiento | Solo para el ámbito Corrida: el nombre del procedimiento, o un guion cuando no se grabó ninguno. |
| INSTANTÁNEA DE LA OCURRENCIA | ID de la corrida | Solo para el ámbito Corrida: el identificador de la corrida, el mismo que muestra Históricos. |
| INSTANTÁNEA DE LA OCURRENCIA | ID del modelo, ID de unidad, ID de la ocurrencia | Los identificadores estables que hay detrás de los nombres, que no cambian al renombrar. |
| SESIÓN DE OBSERVACIÓN | Secuencia del diario | El número de inserción de la fila en el diario, que ordena las filas que comparten marca de tiempo. |
| SESIÓN DE OBSERVACIÓN | ID de la observación | La identidad de la sesión que observó el flanco; todos los flancos de una sesión la comparten. |
| SESIÓN DE OBSERVACIÓN | Secuencia de la transición | El orden del flanco dentro de la sesión, empezando por uno. Un hueco significa un flanco que el diario no pudo persistir. |
| SESIÓN DE OBSERVACIÓN | Inicio | Cuándo empezó la sesión, como marca de tiempo completa. |
| SESIÓN DE OBSERVACIÓN | Motivo | Corrida iniciada, Corrida reanudada, Vigilancia iniciada, Observación fuera de corrida reanudada o Definición modificada. |
| CONFIGURACIÓN CONGELADA | Condición | La condición JavaScript que la sesión juzgó de verdad. |
| CONFIGURACIÓN CONGELADA | Retardo a la activación / desactivación | "x ms / y ms", el antirrebote que usó la sesión. |
| CONFIGURACIÓN CONGELADA | ID de los canales referenciados | Los identificadores de los canales que condicionaron la condición, separados por puntos y comas. |

**Copiar el evento** copia una línea: "marca de tiempo | Ocurrencia | gravedad | nombre | resumen |
mensaje | EventId=… | OccurrenceId=… | ObservationId=… | ObservationSequence=… |
ObservationStartedAt=… | ObservationReason=… | Condition=… | OnDelayMs=… | OffDelayMs=… |
ReferencedChannelIds=…".

## Columnas de la exportación {#export-columns}

El CSV y el JSON llevan los mismos campos, en este orden: `Timestamp` (el encabezado del CSV agrega la
referencia horaria, "Timestamp (UTC-03:00)"), `JournalSequence`, `Severity`, `Name`, `Transition`,
`Scope`, `Model`, `ModelId`, `Unit`, `UnitId`, `Procedure`, `RunId`, `Message`, `EventId`,
`OccurrenceId`, `ObservationId`, `ObservationSequence`, `ObservationStartedAt`, `ObservationReason`,
`Condition`, `OnDelayMs`, `OffDelayMs` y `ReferencedChannelIds` (separados por puntos y comas en el
CSV, un arreglo en el JSON). El JSON es un sobre con `TimeZone` y `Events`. Los nombres de archivo
son `occurrence-history-<yyyyMMdd-HHmmss>.csv` y `.json`. El CSV sigue la preferencia de separador
decimal de la estación como cualquier otra exportación: con decimales de punto el separador de lista
es `,`, con decimales de coma es `;`. Una celda que empieza por `=`, `+`, `-` o `@` se prefija con un
apóstrofo para que la hoja de cálculo la lea como texto.

## Dónde más se graba una ocurrencia {#where-else-an-occurrence-is-recorded}

Una observación de corrida se escribe primero en el archivo de la corrida y después se copia aquí con
el mismo identificador de evento y el contexto de la corrida; si la copia falla, el archivo de la
corrida sigue guardando el flanco y Consola lleva una línea de Error que lo dice. Una observación
fuera de corrida existe solo aquí. Todo flanco deja además una línea de Consola bajo el área Process:
una activación en el nivel de su gravedad (Crítica como error, Advertencia como advertencia,
Información como información), una pérdida de señal en ese mismo nivel, y un restablecimiento y una
restauración como información. Una activación levanta además una notificación dentro de la ventana
titulada "Ocurrencia · " seguida del nombre de la unidad y, para una activación de gravedad
Advertencia o Crítica observada durante una corrida, una notificación
del sistema mientras la ventana está oculta o minimizada.

## Estados vacíos y línea de estado {#empty-states-and-the-status-line}

- "Todavía no hay ocurrencias" con "Aquí aparecerán las transiciones de ocurrencias de las corridas
  y de la vigilancia continua fuera de corrida."
- "No hay ocurrencias que coincidan con estos filtros" con "Ajuste la gravedad o los términos de
  búsqueda para ampliar este histórico."
- La línea de estado dice "N mostrados · página 1", después " · filtrado" cuando hay una búsqueda,
  una gravedad o un periodo en vigor; a la derecha, "1 seleccionado" y "Actualizado
  hh:mm:ss".

## Qué no hace la pestaña Ocurrencias {#what-the-occurrences-tab-does-not-do}

- No define, arma ni edita una ocurrencia
  ([Process > Preparación > Ocurrencias](process-occurrences)).
- No empareja flancos en episodios con duración: esa vista derivada, con sus clasificaciones
  Interrumpida e Incompleta, está en [Históricos](histories) para una corrida y en los paneles
  propios de la unidad.
- No tiene filtro de unidad, de corrida, de ámbito ni de fecha; busque por el nombre de la unidad,
  del modelo o del procedimiento, o abra la corrida en Históricos.
- No muestra ningún estado en vivo: si una ocurrencia está activa ahora mismo se lee en el panel de
  la unidad, no aquí.
