# Logic

> La página Logic, su columna Espacio de direcciones, las carpetas, la barra de comandos, el ciclo de la lógica y el punto único de escritura que hay detrás de cada panel, y los tres permisos que deciden lo que dibuja la página.

Logic es la tercera entrada de la barra de navegación. Se abre para cualquier rol que tenga **Ver Logic**, y su encabezado dice "Defina variables (valores derivados o escribibles) y acciones (scripts que las escriben), compuestas sobre el espacio de direcciones." Es una página de maestro y detalle ([cómo funcionan las páginas](app-conventions)): una columna titulada **Espacio de direcciones** a la izquierda, y una barra de comandos y un panel de detalle a la derecha. Todo lo que usted edita aquí se guarda solo conforme escribe; no hay ningún botón Guardar en toda la página.

## En esta área {#in-this-area}

| Página | Qué cubre |
| --- | --- |
| [El espacio de direcciones](logic-address-space) | Las siete raíces reservadas, cómo se escribe y se higieniza una dirección, la caja de filtro y las tres maneras de capturar una dirección. |
| [Variables](logic-variables) | El editor de la variable: identidad y dirección, las clases Expresión y Memoria, la tarjeta Valor, Poner el valor. |
| [Expresiones](logic-expressions) | El lenguaje de expresiones, la superficie de lectura de un punto, las reglas que impone el evaluador, el editor de scripts. |
| [Acciones](logic-actions) | El editor de la acción, lo que un script puede escribir, todos los mensajes de validación, Ejecutar y Activar/Desactivar. |
| [Disparadores](logic-triggers) | El editor del disparador y el planificador por intervalo. |
| [Alarmas](logic-alarms) | El editor de la alarma, la máquina de estados, el anuncio, Reconocer y Reconocer todas. |
| [De otras páginas](logic-from-other-pages) | Las raíces System, Server, Connector y Process, el panel del punto y el aviso que nombra la página que las edita. |

La raíz **Assets** de esa misma columna es un grupo aparte: [Recursos](logic-assets) cubre Images, Icons, Colors, Symbols y Connection types.

## La columna Espacio de direcciones {#the-address-space-column}

La columna lista las raíces del espacio de direcciones bajo dos títulos. **Definido aquí** contiene lo que esta página crea y edita: **Variables**, **Alarms**, **Actions**, **Triggers** y **Assets**. **De otras páginas** contiene lo que solo muestra: **System**, **Server**, **Connector** y **Process**. Cada raíz del primer título lleva un conteo (Variables y Alarms cuentan sus definiciones, Actions y Triggers las suyas, Assets la suma de sus cinco categorías), y la raíz Alarms, cada carpeta de alarmas y cada fila de alarma llevan un punto de color con la peor prioridad que tengan activa o esperando reconocimiento; el punto se limpia en cuanto se responde la alarma.

El árbol es perezoso: una rama se carga cuando usted la despliega. Los valores en vivo nunca se dibujan en el árbol; los muestra el panel de detalle del nodo seleccionado, actualizado dos veces por segundo.

| Control | Qué hace |
| --- | --- |
| Filtrar… | Reduce el árbol a las filas cuyo nombre contiene el texto, sin distinguir mayúsculas. Una carpeta sobrevive cuando cualquier descendiente coincide, y se abre hasta sus coincidencias; la raíz Assets se reduce a las categorías cuyo nombre coincide, o viene entera cuando solo coincide su propio nombre; una raíz del espacio de direcciones cuyo propio nombre coincide se queda listada y carga su rama al desplegarla, mientras que las secciones Actions y Triggers listan solo las filas que coinciden. |
| Nuevo… (pie de la columna) | Abre el menú de creación: **Nueva variable**, **Nueva acción**, **Nuevo disparador**, **Nueva alarma**, y luego **Nueva carpeta** con un destino por sección (Variables, Alarms, Actions, Triggers). Todo lo que se hace aquí aterriza en la raíz de su sección con el primer nombre libre de las series `Variable1`, `Action1`, `Trigger1`, `Alarm1` o `Folder1`. Una definición nueva no se abre (véase [Crear y copiar](#creating-and-copying)); una carpeta nueva abre su campo de nombre en su fila del árbol. Se dibuja solo para un rol con **Configurar Logic**; queda en gris con el motivo mientras la estación está bloqueada. |
| Expandir todo / Contraer todo | Abre todas las ramas (cargando cada nivel conforme se abre) o cierra todo de vuelta hasta las raíces. |
| Clic derecho | Sobre una raíz de sección, una de sus carpetas, una fila de definición o la fila Images, Icons, Colors o Symbols: selecciona la fila y abre su menú (más abajo). Sobre un nodo de otra página no abre nada. |

El menú del clic derecho lleva, según la fila y el rol: **Nueva variable / Nueva acción / Nuevo disparador / Nueva alarma** (dentro de la carpeta o de la raíz en la que usted hizo clic), **Nueva carpeta** (atenuada y con el motivo en una carpeta que ya está a tres niveles), **Ejecutar** (en las filas de acción), **Reconocer** (en las filas de alarma), **Reconocer todas** (la raíz Alarms), **Activar** o **Desactivar** (acciones, disparadores y alarmas), **Mover a** (un submenú con la raíz de la sección y todas las carpetas en las que se puede archivar la fila), **Copiar**, la eliminación con el nombre que le da la barra (**Eliminar la variable** y así), y en una carpeta **Renombrar la carpeta** y **Quitar la carpeta**. En Images, Icons, Colors y Symbols lleva su barra: **Importar imagen…**, **Nuevo icono de usuario**, **Nuevo color**, **Nuevo símbolo de usuario**, **Importar símbolo…** y **Copiar la instrucción para el chat**. Un rol sin Configurar Logic solo recibe Ejecutar, Reconocer y Reconocer todas cuando tiene Operar Logic, y Copiar la instrucción para el chat en Symbols; una fila sin ninguno de ellos no abre menú.

El área de detalle está vacía hasta que usted seleccione algo: "Seleccione un nodo para inspeccionarlo: las variables, las acciones, los disparadores y las alarmas abren su editor. Cree uno con Nuevo."

## La barra de comandos {#the-command-bar}

La barra dibuja los verbos del nodo seleccionado. Lo que el rol nunca permite no se dibuja; lo que la situación rechaza en este momento se queda dibujado, en gris, con el motivo en su información emergente: "La configuración está bloqueada mientras una unidad está en marcha." durante una operación de ingeniería, "Runtime detenido" mientras la estación corre en solo lectura.

| Selección | Grupo inicial | Grupo final (de peligro) |
| --- | --- | --- |
| Una de sus carpetas | Nueva variable / acción / disparador / alarma (la clase que contiene su sección), Nueva carpeta (en gris, "Esta carpeta ya está a la profundidad máxima a la que se anidan las carpetas.", en el tope de profundidad), Renombrar la carpeta | Quitar la carpeta |
| Una variable | Copiar | Eliminar la variable |
| Una acción | Ejecutar, Activar o Desactivar, Copiar | Eliminar la acción |
| Un disparador | Activar o Desactivar, Copiar | Eliminar el disparador |
| Una alarma | Reconocer, Activar o Desactivar, Copiar | Eliminar la alarma |
| La raíz Alarms | Reconocer todas | |
| Assets, Images | Importar imagen… | |
| Assets, Icons | Nuevo icono de usuario | |
| Assets, Colors | Nuevo color | |
| Assets, Symbols | Nuevo símbolo de usuario, Importar símbolo…, Copiar la instrucción para el chat | |
| Un nodo System, Server, Connector o Process | El [aviso de que se edita en otro lado](logic-from-other-pages#the-edited-elsewhere-notice) y su botón Abrir | |

**Copiar** duplica la definición seleccionada en la raíz de su sección, con el nombre propio del origen cuando está libre y si no con `Nombre (2)`, `Nombre (3)` y así, y resalta la copia en la tabla de esa raíz en lugar de abrirla (véase [Crear y copiar](#creating-and-copying)); una alarma copiada arranca en reposo, un disparador copiado arranca sin programar, y una acción copiada no tiene ninguna ejecución registrada. **Activar** y **Desactivar** cambian la bandera Activado de la definición por el mismo guardado automático que cualquier campo. Todo **Eliminar** pregunta primero ("¿Eliminar 'X'? … Esta acción no se puede deshacer.") e informa "Eliminado." en el registro de acciones; eliminar una variable o una alarma deja sin resolver todas las expresiones, los scripts, las condiciones y los vínculos de panel de control que nombraran su dirección, que es lo que lista [Validación](validation). Una eliminación aterriza en el padre de lo eliminado: la pantalla va a la carpeta en la que estaba archivada la definición, o a la raíz de su sección, seleccionada y abierta en el árbol con su tabla de lo que queda, y **Quitar la carpeta** aterriza igual en la carpeta de arriba o en la raíz de la sección.

## Crear y copiar {#creating-and-copying}

Crear nunca abre lo que creó, y una copia es una creación. **Nueva variable**, **Nueva acción**, **Nuevo disparador** y **Nueva alarma**, ya sea desde el **Nuevo…** de la columna, desde el menú del clic derecho de una raíz de sección o de una carpeta, o desde la barra de una carpeta abierta, crean la fila con el primer nombre libre de su serie y llevan la pantalla a la página de su padre: la carpeta en la que se archivó, o la raíz de la sección. El árbol selecciona ese padre y lo despliega, la tabla de la página resalta la fila nueva y la desplaza hasta quedar a la vista, y el registro de acciones dice "Elemento 'Variable1' creado. Ábralo para editarlo." Una creación hecha desde la barra de la propia carpeta deja la pantalla en esa carpeta. **Copiar** hace lo mismo en la raíz de su sección, y el registro de acciones dice "Copiado en 'Setpoint (2)'. Abra la copia para editarla." Un filtro escrito en la caja **Filtrar…** se borra al llegar, para que el padre y la fila nueva estén en el árbol y puedan mostrarse seleccionados y desplegados.

La página de una raíz de sección o de una de sus carpetas es una tabla de lo que contiene, con **Nombre**, **Dirección** y **Valor**, y al final de cada fila un **Abrir** que abre la definición igual que su fila en el árbol (en la raíz Alarms, un rol con **Operar Logic** encuentra ahí también **Reconocer**). Una variable cuyo tipo de salida es Icono, Imagen o Valor de color dibuja en su celda Valor su icono, su imagen o su muestra de color, lo bastante pequeño para la fila (un color muestra además su hexadecimal); la celda nunca escribe el código fuente del icono. Pulsar una fila la elige, y la fila elegida es la fila resaltada: el resaltado se mantiene hasta que usted elija otra fila o lleve la columna a cualquier otro sitio. Una carpeta nueva es la excepción: abre su campo de nombre en su fila del árbol.

## Las carpetas {#folders}

Cada una de las cuatro secciones se puede organizar en carpetas. Una carpeta pertenece a una sección y contiene solo los elementos de esa sección; se anida tres niveles como máximo. Una carpeta es organización y nada más: no tiene permiso, ni evaluación, ni estado.

Para **Variables** y **Alarms**, la cadena de carpetas compone la dirección: una variable en `Horno` se lee `Variables.Horno.Consigna`, y una en su subcarpeta `Zona1` se lee `Variables.Horno.Zona1.Consigna`. Un nivel de una sección es un espacio de nombres de un solo segmento, compartido por sus carpetas y sus definiciones: dos carpetas pueden tener cada una una `Consigna`, pero nada archivado en el mismo nivel puede higienizarse al mismo segmento, y el editor rechaza un nombre así conforme usted escribe, nombrando la dirección que ya está tomada. Las **Actions** y los **Triggers** se referencian por identidad, así que sus carpetas organizan solo el árbol y sus paneles muestran una línea de ubicación en lugar de una dirección.

| Comando | Qué pasa |
| --- | --- |
| Nueva carpeta | Crea una carpeta vacía llamada `FolderN` y abre su campo de nombre en la fila del árbol; dejar el campo vacío o sin cambiar conserva ese nombre. |
| Renombrar la carpeta | Abre el campo de nombre en la fila. Todas las direcciones que hay debajo de la carpeta se mueven con ella, todas las referencias se reescriben, y el registro de acciones dice cuántas ("Carpeta renombrada; 3 referencias actualizadas."). |
| Mover a | Archiva una carpeta o una definición bajo otra carpeta de la misma sección, o de vuelta en la raíz de la sección; las direcciones y las referencias van detrás. La lista ofrece solo los destinos legales: nunca la carpeta misma, ni una de sus propias subcarpetas, ni otra sección, ni un nivel en el que sus subcarpetas pasarían el tope de profundidad. |
| Quitar la carpeta | Pregunta primero, y dice qué se mueve: "Sus 3 elementos se mueven a Variables; no se elimina nada. Las referencias a las direcciones que se mueven se actualizan." Los elementos y las subcarpetas se vuelven a archivar un nivel arriba; el retiro se rechaza cuando dos de ellos chocarían en el destino. |

## El ciclo de la lógica y la cola {#the-sweep-and-the-queue}

El runtime corre sobre dos carriles, y ninguno de los dos espera nunca al equipo. El **ciclo** corre cada 100 ms sobre una sola cola secuencial: evalúa todas las variables de expresión y después todas las condiciones de alarma activadas, en ese orden, así que una condición lee los valores de variable de este mismo ciclo, y lleva además las escrituras de memoria y de tag que llegan de otras partes y los reconocimientos de alarma. El **carril de acciones** corre los scripts de acción, de uno en uno, en el orden en que se pidieron. Un recorrido aparte, también cada 100 ms, lanza al carril de acciones los [disparadores](logic-triggers) que vencieron.

Como los carriles son independientes, un ciclo puede caer en medio de un script, así que dos lecturas de un mismo script pueden ver ciclos distintos; a cambio, un script que se detiene a esperar a un dispositivo retiene solo a las acciones que van detrás, y nunca a las expresiones, a las alarmas ni al operador. Las escrituras no compiten por él: el orden se guarda donde está el cable, una cola por dispositivo (véase más abajo). Los consumidores (los paneles de control, los canales, esta página) leen el estado publicado; nada de esta página dispara una evaluación a mano.

## Escribir valores {#writing-values}

Todas las escrituras pasan por un punto único de escritura, sea lo que sea que las haya arrancado: la asignación de un script o un `Write(...)`, el campo **Establecer el valor** de una variable de memoria, un mando de un panel de control, una receta de Process, el agente, un cliente OPC UA externo escribiendo un nodo público, o un cliente Modbus escribiendo una fila del mapa del [servidor Modbus](connector-modbus-server) que permite escribir. El punto único rechaza un valor que no es finito o que no se puede convertir al tipo del destino, rechaza una fuente que retiene una receta en marcha o un enclavamiento (nombrando a quien la retiene), registra la escritura como valor anterior a valor nuevo bajo su fuente (Operador, MCP, la corrida) y la aplica. Lo que el punto único decide, lo decide sin preguntarle nada a nadie: el valor, el destino, el bloqueo, y hasta si el dispositivo está conectado siquiera. Una escritura de tag que admite se entrega enseguida a la cola de entrega de ese dispositivo dentro del Connector, donde los valores que se le deben salen de uno en uno, en el orden en que llegaron, mientras los demás dispositivos se atienden en paralelo; un valor que una escritura más nueva al mismo tag rebasa ahí nunca sale de la cola, y al equipo se le dice el más nuevo. Quien pidió es quien espera la respuesta, fuera de la Lógica y en su propio código: el componente del panel de control, la escritura manual de la [página del tag](connector-tags#the-live-value-card), la herramienta del agente, el cliente OPC UA externo, el cliente Modbus, una receta en marcha, y un script solo donde dijo `WriteAndWait`. Una escritura cuya fuente es una acción es la excepción: va solo a la [captura detallada](events-console#detailed-capture), nunca a la consola de Eventos, porque un script que escribe en cada ciclo produce valores por millares y sepultaría bajo ellos las novedades de la estación. Lo que la consola sí lleva de una acción son sus fallas. Una escritura de tag toma el valor de ingeniería y deshace la [cadena de conversión](connector-value-pipeline) del tag hasta el valor bruto que toma el dispositivo. Los detalles están en [Variables](logic-variables#set-value) y en [Acciones](logic-actions#what-an-action-may-write).

## Los permisos y los bloqueos {#permissions-and-locks}

| Permiso | Qué permite aquí |
| --- | --- |
| Ver Logic | Abrir la página y leer todo lo que hay en ella, los valores en vivo incluidos. |
| Configurar Logic | Crear, editar, renombrar, mover, copiar, activar, desactivar y eliminar variables, acciones, disparadores, alarmas y carpetas, y curar la biblioteca de recursos. |
| Operar Logic | Escribir un valor de memoria, ejecutar una acción y reconocer alarmas, aquí, en los paneles de control y en la página Eventos. |

Un rol solo con Ver Logic lee toda la página: los editores quedan inertes bajo una nota ("Su rol puede ver Logic pero no configurarlo (variables, acciones, disparadores, alarmas y recursos).") y no se dibuja ningún verbo de configurar ni de operar. Un rol con Operar pero sin Configurar conserva vivos Ejecutar, Reconocer, Reconocer todas y Poner el valor. Mientras una unidad de Process retiene la estación, la página muestra el aviso de bloqueo de ingeniería y todos los verbos y campos de configuración quedan en gris; Ejecutar, Reconocer y Poner el valor siguen disponibles. Mientras el runtime está detenido, tanto configurar como operar se rechazan con "Runtime detenido"; el árbol y los paneles se siguen leyendo, pero sin ningún dato en vivo. El catálogo de bits está en [Permisos](users-permissions).

## Lo que la página no hace {#what-the-page-does-not-do}

No hay Guardar ni Deshacer: una tecla es un cambio guardado (el registro de acciones dice "Guardado.") y un guardado rechazado recarga el campo a lo que tiene la estación. Las definiciones que el agente crea, cambia o elimina con sus propias herramientas, o que cambia otra ventana, llegan por sí solas a la columna abierta. Un editor abierto sobre una definición eliminada así se cierra, y el registro de acciones la nombra y dice que se eliminó fuera del editor. El histórico de alarmas, la consola de Eventos y los paneles de control viven en sus propias páginas.
