# Logic

> A página Logic, a coluna Espaço de endereços, as pastas, a barra de comandos, a varredura e o funil de escrita atrás de todo painel, e as três permissões que decidem o que a página desenha.

A Logic é a terceira entrada do trilho de navegação. Ela abre para qualquer papel que tenha **Ver a lógica**, e o cabeçalho dela diz "Defina variáveis (valores derivados ou escrevíveis) e ações (scripts que escrevem nelas), compostas sobre o espaço de endereços." É uma página de mestre e detalhe ([como as páginas funcionam](app-conventions)): uma coluna chamada **Espaço de endereços** à esquerda, uma barra de comandos e um painel de detalhes à direita. Tudo que você edita aqui salva sozinho enquanto você digita; não existe botão Salvar em lugar nenhum da página.

## Nesta área {#in-this-area}

| Página | Assunto |
| --- | --- |
| [O espaço de endereços](logic-address-space) | As sete raízes reservadas, como um endereço é escrito e higienizado, a caixa de filtro e as três maneiras de digitar um endereço. |
| [Variáveis](logic-variables) | O editor de variável: identidade e endereço, os tipos Expressão e Memória, o cartão Valor, o Definir valor. |
| [Expressões](logic-expressions) | A linguagem de expressão, a superfície de leitura de um ponto, as regras que o avaliador impõe, o editor de script. |
| [Ações](logic-actions) | O editor de ação, o que um script pode escrever, todas as mensagens de validação, o Executar e o Habilitar/Desabilitar. |
| [Gatilhos](logic-triggers) | O editor de gatilho e o agendador por intervalo. |
| [Alarmes](logic-alarms) | O editor de alarme, a máquina de estados, a anunciação, o Reconhecer e o Reconhecer tudo. |
| [De outras páginas](logic-from-other-pages) | As raízes System, Server, Connector e Process, o painel do ponto e o aviso que nomeia a página que as edita. |

A raiz **Assets** da mesma coluna é um grupo próprio: [Recursos](logic-assets) cobre Images, Icons, Colors, Symbols e Connection types.

## A coluna Espaço de endereços {#the-address-space-column}

A coluna lista as raízes do espaço de endereços sob duas legendas. **Definido aqui** reúne o que esta página cria e edita: **Variables**, **Alarms**, **Actions**, **Triggers** e **Assets**. **De outras páginas** reúne o que ela apenas mostra: **System**, **Server**, **Connector** e **Process**. Toda raiz sob a primeira legenda carrega uma contagem (Variables e Alarms contam as definições deles, Actions e Triggers as delas, Assets a soma das cinco categorias), e a raiz Alarms, toda pasta de alarme e toda linha de alarme carregam um ponto colorido com a pior prioridade que elas contêm que esteja ativa ou aguardando reconhecimento; o ponto se limpa no instante em que o alarme é respondido.

A árvore é preguiçosa: um galho carrega quando você o expande. Valores ao vivo nunca são desenhados na árvore; o painel de detalhes do nó selecionado os mostra, atualizados duas vezes por segundo.

| Controle | O que faz |
| --- | --- |
| Filtrar… | Reduz a árvore às linhas cujo nome contém o texto, sem diferenciar maiúsculas de minúsculas. Uma pasta sobrevive quando qualquer descendente casa e se abre até os acertos dela; a raiz Assets se reduz às categorias cujo nome casa, ou vem inteira quando só o nome dela casa; uma raiz do espaço de endereços cujo próprio nome casa continua listada e carrega o galho dela quando expandida, enquanto as seções Actions e Triggers listam só as linhas que casam. |
| Novo… (rodapé da coluna) | Abre o menu de criação: **Nova variável**, **Nova ação**, **Novo gatilho**, **Novo alarme**, e então **Nova pasta**, com um destino por seção (Variables, Alarms, Actions, Triggers). Tudo que é feito aqui é criado na raiz da seção dele, com o primeiro nome livre das séries `Variable1`, `Action1`, `Trigger1`, `Alarm1` ou `Folder1`. Uma definição nova não é aberta (veja [Criar e copiar](#creating-and-copying)); uma pasta nova abre o campo de nome na linha dela na árvore. Desenhado só para um papel com **Configurar a lógica**; esmaecido com o motivo enquanto a estação está travada. |
| Expandir tudo / Recolher tudo | Abre todos os galhos (carregando cada nível conforme abre) ou fecha tudo de volta até as raízes. |
| Botão direito | Numa raiz de seção, numa pasta sua, numa linha de definição ou na linha Images, Icons, Colors ou Symbols: seleciona a linha e abre o menu dela (abaixo). Nada abre num nó de outra página. |

O menu de contexto carrega, conforme a linha e o papel: **Nova variável / Nova ação / Novo gatilho / Novo alarme** (dentro da pasta ou raiz em que você clicou), **Nova pasta** (esmaecida, com o motivo, numa pasta que já está três níveis abaixo), **Executar** (linhas de ação), **Reconhecer** (linhas de alarme), **Reconhecer tudo** (a raiz Alarms), **Habilitar** ou **Desabilitar** (ações, gatilhos e alarmes), **Mover para** (um submenu com a raiz da seção e toda pasta em que a linha pode ser arquivada), **Copiar**, a exclusão com o nome que a barra dá (**Excluir a variável** e assim por diante), e, numa pasta, **Renomear a pasta** e **Remover a pasta**. Em Images, Icons, Colors e Symbols, carrega a barra delas: **Importar imagem…**, **Novo ícone do usuário**, **Nova cor**, **Novo símbolo do usuário**, **Importar símbolo…** e **Copiar instrução para chat**. Um papel sem Configurar a lógica recebe apenas Executar, Reconhecer e Reconhecer tudo quando tem Operar a lógica, e Copiar instrução para chat em Symbols; uma linha sem nenhum deles não abre menu.

A área de detalhe fica vazia até você selecionar algo: "Selecione um nó para inspecioná-lo: variáveis, ações, gatilhos e alarmes abrem o editor deles. Crie um com Novo."

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

A barra desenha os verbos do nó selecionado. O que o papel nunca permite não é desenhado; o que a situação recusa agora continua desenhado, esmaecido, com o motivo na dica: "A configuração está travada enquanto uma Unidade está em execução." durante uma operação de engenharia, "Runtime parado" enquanto a estação roda em somente leitura.

| Seleção | Grupo inicial | Grupo final (de perigo) |
| --- | --- | --- |
| Uma pasta sua | Nova variável / ação / gatilho / alarme (o tipo que a seção dela contém), Nova pasta (esmaecida com "Esta pasta já está no nível mais profundo em que pastas se aninham." no limite de profundidade), Renomear a pasta | Remover a pasta |
| Uma variável | Copiar | Excluir a variável |
| Uma ação | Executar, Habilitar ou Desabilitar, Copiar | Excluir a ação |
| Um gatilho | Habilitar ou Desabilitar, Copiar | Excluir o gatilho |
| Um alarme | Reconhecer, Habilitar ou Desabilitar, Copiar | Excluir o alarme |
| A raiz Alarms | Reconhecer tudo | |
| Assets, Images | Importar imagem… | |
| Assets, Icons | Novo ícone do usuário | |
| Assets, Colors | Nova cor | |
| Assets, Symbols | Novo símbolo do usuário, Importar símbolo…, Copiar instrução para chat | |
| Um nó System, Server, Connector ou Process | O [aviso de edição em outro lugar](logic-from-other-pages#the-edited-elsewhere-notice) e o botão Abrir dele | |

O **Copiar** duplica a definição selecionada na raiz da seção dela, com o nome da própria origem quando ele está livre e, caso contrário, `Nome (2)`, `Nome (3)` e assim por diante, e destaca a cópia na tabela dessa raiz em vez de abri-la (veja [Criar e copiar](#creating-and-copying)); um alarme copiado começa em Sem alarme, um gatilho copiado começa sem agenda, uma ação copiada não tem execução registrada. **Habilitar** e **Desabilitar** viram o sinalizador Habilitado da definição pelo mesmo salvamento automático de qualquer campo. Todo **Excluir** pergunta antes ("Excluir 'X'? … Isso não pode ser desfeito.") e relata "Excluído." no feed de ações; excluir uma variável ou um alarme deixa sem resolução toda expressão, script, condição e vínculo de dashboard que nomeava o endereço deles, o que a [Validação](validation) lista. Uma exclusão cai no pai do que excluiu: a tela vai para a pasta em que a definição estava arquivada, ou para a raiz da seção dela, selecionada e aberta na árvore com a tabela do que sobrou, e **Remover a pasta** cai do mesmo jeito na pasta de cima ou na raiz da seção.

## Criar e copiar {#creating-and-copying}

Criar nunca abre o que foi criado, e uma cópia é uma criação. **Nova variável**, **Nova ação**, **Novo gatilho** e **Novo alarme**, seja pelo **Novo…** da coluna, pelo menu do botão direito de uma raiz de seção ou de uma pasta, ou pela barra de uma pasta aberta, criam a linha com o primeiro nome livre da série dela e levam a tela à página do pai: a pasta em que ela foi arquivada, ou a raiz da seção. A árvore seleciona esse pai e o expande, a tabela da página destaca a linha nova e a rola até ficar à vista, e o feed mostra "Item 'Variable1' criado. Abra-o para editá-lo." Um criar feito pela barra da própria pasta deixa a tela nessa pasta. O **Copiar** faz o mesmo na raiz da seção dele, e o feed mostra "Copiado para 'Setpoint (2)'. Abra a cópia para editá-la." Um filtro digitado na caixa **Filtrar…** é limpo na chegada, para que o pai e a linha nova estejam na árvore e possam aparecer selecionados e abertos.

A página de uma raiz de seção ou de uma pasta sua é uma tabela do que ela guarda, com **Nome**, **Endereço** e **Valor**, e no fim de cada linha um **Abrir** que abre a definição do mesmo jeito que a linha dela na árvore (na raiz Alarms, um papel com **Operar a lógica** encontra ali também o **Reconhecer**). Uma variável cujo tipo de saída é Ícone, Imagem ou Cor desenha na célula Valor o seu ícone, a sua imagem ou a sua amostra de cor, pequeno o bastante para a linha (uma cor mostra também o seu hexadecimal); a célula nunca escreve o código-fonte do ícone. Pressionar uma linha a escolhe, e a linha escolhida é a linha destacada: o destaque fica até você escolher outra linha ou levar a coluna para qualquer outro lugar. Uma pasta nova é a exceção: ela abre o campo de nome na linha dela na árvore.

## Pastas {#folders}

Cada uma das quatro seções pode ser organizada em pastas. Uma pasta pertence a uma seção e contém só os itens daquela seção; ela se aninha em três níveis, no máximo. Uma pasta é organização e nada mais: ela não tem permissão, nem avaliação, nem estado.

Em **Variables** e **Alarms**, a cadeia de pastas compõe o endereço: uma variável em `Forno` lê `Variables.Forno.Setpoint`, e uma na subpasta `Zona1` dela lê `Variables.Forno.Zona1.Setpoint`. Um nível de uma seção é um espaço de nomes de segmento único, compartilhado pelas pastas e pelas definições dele: duas pastas podem ter cada uma um `Setpoint`, mas nada arquivado no mesmo nível pode higienizar para o mesmo segmento, e o editor recusa um nome assim enquanto você digita, nomeando o endereço já ocupado. **Actions** e **Triggers** são referenciados por identidade, então as pastas deles organizam apenas a árvore, e os painéis deles mostram uma linha de localização em vez de um endereço.

| Comando | O que acontece |
| --- | --- |
| Nova pasta | Cria uma pasta vazia chamada `FolderN` e abre o campo de nome dela na linha da árvore; deixar o campo vazio ou sem mudança mantém aquele nome. |
| Renomear a pasta | Abre o campo de nome na linha. Todo endereço abaixo da pasta se move com ela, toda referência é reescrita, e o feed diz quantas ("Pasta renomeada; 3 referências atualizadas."). |
| Mover para | Arquiva uma pasta ou uma definição sob outra pasta da mesma seção, ou de volta na raiz da seção; endereços e referências acompanham. A lista oferece só os destinos legais: nunca a própria pasta, nunca uma subpasta dela, nunca outra seção, nem um nível em que as subpastas dela passariam do limite de profundidade. |
| Remover a pasta | Pergunta antes, dizendo o que se move: "Os 3 itens dela vão para Variables; nada é excluído. As referências aos endereços que se movem são atualizadas." Os itens e as subpastas são rearquivados um nível acima; a remoção é recusada quando dois deles colidiriam no destino. |

## A varredura e a fila {#the-sweep-and-the-queue}

O runtime roda em duas faixas, e nenhuma delas jamais espera por equipamento. A **varredura** roda a cada 100 ms numa fila sequencial: ela avalia toda variável de expressão e depois toda condição de alarme habilitada, nessa ordem, então uma condição lê os valores de variável desta varredura, e ela também carrega as escritas de memória e de tag que chegam de fora e os reconhecimentos de alarme. A **faixa das ações** roda os scripts de ação, um de cada vez, na ordem em que foram pedidos. Uma varredura separada, também a cada 100 ms, dispara os [gatilhos](logic-triggers) vencidos na faixa das ações.

Como as faixas são independentes, uma varredura pode acontecer no meio de um script, então duas leituras de um mesmo script podem ver ciclos diferentes; em troca, um script que para para esperar um dispositivo segura só as ações atrás dele, e nunca as expressões, os alarmes nem o operador. As escritas não disputam por isso: a ordem é mantida onde o fio está, uma fila por dispositivo (veja abaixo). Os consumidores (dashboards, canais, esta página) leem o estado publicado; nada nesta página dispara uma avaliação à mão.

## Escrita de valores {#writing-values}

Toda escrita passa por um funil, seja o que for que a começou: a atribuição de um script ou o `Write(...)`, o campo **Definir o valor** de uma variável de memória, um controle de dashboard, uma receita do Process, o agente, um cliente OPC UA externo escrevendo um nó público, um cliente Modbus escrevendo uma linha do mapa do [servidor Modbus](connector-modbus-server) que permite escrita. O funil recusa um valor que não é finito ou que não converte para o tipo do alvo, recusa uma origem que uma receita em execução ou um intertravamento segura (nomeando quem segura), registra no diário a escrita como valor antigo para valor novo, sob a origem dela (Operador, MCP, a execução), e a aplica. O que o funil decide, ele decide sem perguntar nada a ninguém: o valor, o alvo, a trava, e se o dispositivo está sequer conectado. Uma escrita de tag que ele admite é então entregue à fila de entrega do próprio dispositivo, dentro do Connector, onde os valores devidos àquele dispositivo saem um de cada vez, na ordem em que chegaram, enquanto os outros dispositivos são atendidos em paralelo; um valor que uma escrita mais nova na mesma tag ultrapassa ali nunca sai da fila, e o mais novo é o que o equipamento recebe. Quem pediu é quem espera a resposta, fora da Lógica e no próprio código dele: o componente do dashboard, a escrita manual da [página da tag](connector-tags#the-live-value-card), a ferramenta do agente, o cliente OPC UA externo, o cliente Modbus, uma receita em execução, e um script só onde ele disse `WriteAndWait`. Uma escrita cuja origem é uma ação é a exceção: ela vai só para a [captura detalhada](events-console#detailed-capture), nunca para o console de Eventos, porque um script que escreve a cada varredura produz valores aos milhares e enterraria as notícias da estação embaixo deles. O que o console carrega de uma ação são as falhas dela. Uma escrita de tag recebe o valor de engenharia e reverte a [cadeia de conversão](connector-value-pipeline) da tag até o valor bruto que o dispositivo recebe. Os detalhes estão em [Variáveis](logic-variables#set-value) e [Ações](logic-actions#what-an-action-may-write).

## Permissões e travas {#permissions-and-locks}

| Permissão | O que ela libera aqui |
| --- | --- |
| Ver a lógica | Abrir a página e ler tudo nela, valores ao vivo incluídos. |
| Configurar a lógica | Criar, editar, renomear, mover, copiar, habilitar, desabilitar e excluir variáveis, ações, gatilhos, alarmes e pastas, e curar a biblioteca de recursos. |
| Operar a lógica | Escrever um valor de memória, executar uma ação e reconhecer alarmes, aqui, nos dashboards e na página Eventos. |

Um papel só com Ver a lógica lê a página inteira: os editores ficam inertes sob uma nota ("Seu papel pode ver a Logic, mas não pode configurá-la (variáveis, ações, gatilhos, alarmes e recursos).") e nenhum verbo de configurar ou operar é desenhado. Um papel com Operar e sem Configurar mantém vivos o Executar, o Reconhecer, o Reconhecer tudo e o Definir valor. Enquanto uma unidade do Process segura a estação, a página mostra o aviso de trava de engenharia e todo verbo de configurar e todo campo de editor ficam esmaecidos; o Executar, o Reconhecer e o Definir valor continuam disponíveis. Enquanto o runtime está parado, tanto configurar quanto operar recusam com "Runtime parado"; a árvore e os painéis continuam legíveis, mas não carregam dado ao vivo. O catálogo de bits está em [Permissões](users-permissions).

## O que a página não faz {#what-the-page-does-not-do}

Não existe Salvar nem Desfazer: uma tecla digitada é uma mudança persistida (o feed diz "Salvo.") e um salvamento recusado recarrega o campo para o que a estação guarda. Definições que o agente cria, altera ou exclui pelas ferramentas dele, ou que outra janela altera, chegam sozinhas à coluna aberta. Um editor aberto sobre uma definição excluída assim fecha, e o feed diz o nome dela e que ela foi excluída fora do editor. O histórico de alarmes, o console de Eventos e os dashboards vivem nas páginas deles.
