> For the complete documentation index, see [llms.txt](https://navixy.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://navixy.com/docs/user/pt-br/guide/account/iot-logic/nodes/missing-values-in-expressions.md).

# Valores ausentes em expressões

Entenda por que uma fórmula ou condição do IoT Logic não produz valor quando falta um valor de que ela precisa, e quais padrões de comparação evitam isso.

Fórmulas e condições no IoT Logic funcionam com os valores que um dispositivo GPS envia. Quando um valor de que uma fórmula precisa está ausente, a maioria dos operadores não consegue produzir um resultado, e a fórmula não produz nada: não `falso`, e não zero. Esta página explica quando um valor some, como é a falha e como escrever fórmulas e condições que continuam funcionando. Ela é destinada a qualquer pessoa que configure um fluxo do IoT Logic, e pressupõe nenhum conhecimento de programação.

A página se aplica aos dois locais em que você escreve uma expressão: o **Fórmula** campo de um [Iniciar Atributo](/docs/user/pt-br/guide/account/iot-logic/nodes/initiate-attribute-node.md) nó, e o **campo de Expressão de condição (JEXL)** campo de um [Lógica](/docs/user/pt-br/guide/account/iot-logic/nodes/logic-node.md) nó.

## Quando uma expressão não consegue produzir um valor

Um valor vazio interrompe a expressão inteira. Isso se aplica em qualquer lado de um cálculo, de uma comparação de tamanho, de um teste de prefixo de texto ou de uma operação lógica `!`, `&&`, ou `||`. Em uma fórmula e no Analisador de dados, um valor vazio aparece como `null`.

Ler um atributo que um dispositivo GPS nunca enviou não é um erro por si só. O que para é o operador que então precisa trabalhar com o valor vazio. Um único valor vazio interrompe a expressão inteira, inclusive as partes que tinham valores. Uma condição que testa quatro geocercas para na primeira que não consegue responder, e as outras três nunca são testadas. A exceção é um termo anterior na expressão que já definiu o resultado.

## O que você vê quando uma expressão não produz nada

Nada indica a falha. O resultado depende de qual nó contém a expressão:

| Onde a expressão é executada                                        | O que acontece com esse pacote de dados                                                                        |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Fórmula** campo de um **Iniciar Atributo** nó                     | O atributo não tem valor para esse pacote, e o Analisador de dados o mostra como `null`.                       |
| **campo de Expressão de condição (JEXL)** campo de um **Lógica** nó | Os dados saem pela conexão ELSE, e o nó armazena seu próprio atributo como um valor vazio, e não como `falso`. |

{% hint style="warning" %}
Nada informa a falha. Nenhum erro aparece no fluxo, nenhum contador muda, e todo outro atributo ainda é calculado normalmente. O único sinal é o próprio valor ausente, então um fluxo pode parecer saudável enquanto um atributo não produz valor por semanas.

Salvar um fluxo também não prova que uma fórmula funcione. A verificação executada quando você salva confirma que a expressão está escrita corretamente. Ela não executa a expressão com os dados do seu dispositivo GPS, então uma fórmula que não produz nada em todos os pacotes ainda é salva sem um aviso.
{% endhint %}

## Como cada operador lida com um valor vazio

Quatro operadores sempre continuam funcionando com um valor vazio: `==`, `!=`, `=~`{{longitude}} `!~`. Os operadores `&&` Webhook `||` continuam funcionando somente quando o lado lido primeiro define a resposta. Todo outro operador para.

Esta tabela aborda um atributo que você referencia pelo nome, que é a forma que [preenchimento automático](/docs/user/pt-br/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#autofill-attribute-names) insere. Quatro operadores se comportam de forma diferente quando o valor vem de `value()` em vez disso. Consulte [Leitura pelo nome ou com value()](#reading-by-name-or-with-value).

| Operador                                                            | Com um valor vazio em qualquer lado                                                                                         |
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `==`, `!=` (igual a, diferente de)                                  | Retorna um verdadeiro sim ou não. `null == null` é `true`{{longitude}} `null != null` é `falso`.                            |
| `=~`, `!~` (está em uma lista, ou corresponde a um padrão de texto) | Retorna um verdadeiro sim ou não. Um valor vazio nunca corresponde, então `=~` retorna `falso` Webhook `!~` retorna `true`. |
| `??` (usar um valor de fallback)                                    | Retorna o valor à direita. Ele substitui apenas um valor vazio.                                                             |
| `?:` (usar um valor de fallback)                                    | Retorna o valor à direita. Ele também substitui `falso`, por `0`, e por texto vazio.                                        |
| `a ? b : c` (escolher entre dois valores)                           | Leva o `c` ramo, assim como faz para `falso`.                                                                               |
| `=^`, `!^`, `=$`, `!$` (começa com, termina com)                    | A expressão não produz nada.                                                                                                |
| `<`, `<=`, `>`, `>=` (comparações de tamanho)                       | A expressão não produz nada.                                                                                                |
| `+`, `-`, `*`, `/`, `%` (aritmética)                                | A expressão não produz nada.                                                                                                |
| `&`, `\|`, `^` (operações de bits)                                  | A expressão não produz nada.                                                                                                |
| `!` (não)                                                           | A expressão não produz nada.                                                                                                |
| `&&`, `\|\|` (e, ou)                                                | A expressão não produz nada, a menos que o lado lido primeiro defina a resposta.                                            |

Os seis operadores de texto se dividem em dois. `=~` Webhook `!~` sobrevive a um valor vazio, mas `=^`, `!^`, `=$`{{longitude}} `!$` não quando o atributo é referenciado pelo nome. Uma condição como `hardware_key !^ 'AB'` parece uma forma segura de excluir um prefixo, mas não produz nada em cada pacote sem `hardware_key`.

O `matemática:` funções não produzem nada quando recebem um valor vazio, então `math:round(engine_temp)` não produz nada quando `engine_temp` está ausente. O `util:` as funções são mais tolerantes e retornam um valor vazio em vez disso, então `util:join` Webhook `util:joinNonNull` ainda produzem um resultado quando um de seus argumentos está ausente. Concatenar texto com `+` não é tolerante: `'Zone: ' + zone_label` não produz nada.

## Operadores lógicos com um valor vazio

A ordem importa para ambos `&&` Webhook `||`. Cada operador lê primeiro o lado esquerdo e para ali quando o lado esquerdo já determina o resultado. A `falso` o lado esquerdo encerra `&&`, e um `true` o lado esquerdo encerra `||`.

| Expressão                     | Resultado                                                                            |
| ----------------------------- | ------------------------------------------------------------------------------------ |
| `falso && (vazio)`            | `falso`. Um lado esquerdo falso encerra o AND, então o lado direito nunca é lido.    |
| `verdadeiro && (vazio)`       | Não produz nada.                                                                     |
| `(vazio) && qualquer coisa`   | Não produz nada. O lado esquerdo é lido primeiro.                                    |
| `verdadeiro \|\| (vazio)`     | `true`. Um lado esquerdo verdadeiro encerra o OR, então o lado direito nunca é lido. |
| `false \|\| (vazio)`          | Não produz nada.                                                                     |
| `(vazio) \|\| qualquer coisa` | Não produz nada. O lado esquerdo é lido primeiro.                                    |

Colocar por último o termo que pode estar vazio ajuda apenas quando o lado esquerdo define o resultado naquele pacote. Você raramente consegue garantir esse resultado, então compare o valor explicitamente em vez disso.

## Leitura pelo nome ou com value()

Quatro operadores fornecem resultados diferentes para o mesmo valor ausente, dependendo de como a fórmula o interpreta. Os operadores são `=^`, `!^`, `=$` Webhook `!$`, as que testam o início ou o fim de um valor de texto.

| Fórmula                                | Resultado quando `motorista_id` nunca foi enviado |
| -------------------------------------- | ------------------------------------------------- |
| `motorista_id !^ 'AB'`                 | Não produz nada                                   |
| `value('driver_id', 0, 'all') !^ 'AB'` | `true`                                            |

Referenciar o atributo pelo nome é o Formulário que [preenchimento automático](/docs/user/pt-br/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#autofill-attribute-names) inserções, então uma condição criada com o seletor de atributos segue o primeiro caminho. Escreva a comparação com `value()` quando você precisar `!^` <https://api.eu.navixy.com/v2/>... `!$` reportar `true` em um pacote que não contém o atributo.

Todo os demais operadores se comportam da mesma forma em ambas as formas. Uma comparação de tamanho, aritmética e `!` todos não produzem nada de qualquer forma, e `==`, `!=`, `=~` Webhook `!~` todos, de qualquer forma, dão um sim ou não de verdade.

A mesma divisão se aplica às duas formas de fallback. `??` Webhook `? :` pode conter um cálculo com falha quando o valor vier de `value()`, e não pode quando vem de um nome:

| Fórmula                                  | Resultado quando `odômetro` nunca foi enviado |
| ---------------------------------------- | --------------------------------------------- |
| `(odômetro + 1) ?? 0`                    | Não produz nada                               |
| `(value('Odômetro', 0, 'all') + 1) ?? 0` | `0`                                           |

Uma planície `??` em um nome ainda funciona, porque nenhum cálculo acontece antes disso. Apenas um cálculo encapsulado dentro `??` <https://api.eu.navixy.com/v2/>... `? :` comporta-se de maneira diferente.

## Comparar um valor explicitamente

Para usar com segurança um valor que pode estar vazio em uma condição, compare-o com `== true` <https://api.eu.navixy.com/v2/>... `== false` em vez de usá-lo isoladamente. Ambos `==` Webhook `!=` dê um verdadeiro sim ou não para um valor vazio, para que um termo sem dados não pare mais toda a condição.

Esta condição faz Paradas em qualquer pacote em que um dos dois atributos esteja ausente:

```jexl
door_open || hood_open
```

Esta condição continua funcionando e retorna sim quando qualquer uma das portas estiver aberta:

```jexl
door_open == true || hood_open == true
```

As funções de geocerca funcionam da mesma forma, porque retornam um valor vazio quando um pacote não traz posição. Esta condição para assim que uma função não consegue responder:

```jexl
leaveGeofence(51577 /* Austin Warehouse */) || leaveGeofence(85269 /* Construction site 1 */)
```

Esta condição testa ambas as geocercas em cada pacote:

```jexl
leaveGeofence(51577 /* Austin Warehouse */) == true || leaveGeofence(85269 /* Construction site 1 */) == true
```

Escolha a comparação que corresponda ao que um pacote sem dados deve ser considerado como:

* `== true` significa "sabido como sim". Um valor vazio fornece `falso`, então um pacote sem dados não corresponde.
* `== false` significa "sabido como não". Um valor vazio fornece `falso`, então um pacote sem dados não corresponde.
* `!= true` significa "não se sabe que é verdadeiro". Um valor vazio resulta em `true`, portanto um pacote sem dados corresponde.

{% hint style="warning" %}
Não use `!` em um valor que possa estar vazio. `!inGeofence(35229)` não produz nada quando a posição é desconhecida, portanto não consegue detectar um dispositivo fora da geocerca. Escreva `inGeofence(35229) == false` para "sabidamente fora", ou `inGeofence(35229) != true` para "não se sabe que esteja dentro".
{% endhint %}

## De onde vêm os valores vazios

Um atributo em uma fórmula resulta em um valor vazio nestes casos:

* O atributo nunca foi enviado para aquele dispositivo GPS.
* O pacote atual não traz o atributo, embora um pacote anterior trouxesse.
* A posição histórica que você solicitou com `value()` ainda não existe, porque o dispositivo enviou menos pacotes do que a posição exige.
* O dispositivo não enviou nada por mais de 30 dias, então a Navixy descartou seu histórico armazenado. Veja [Sintaxe completa](/docs/user/pt-br/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#full-syntax).
* `inGeofence()`, `enterGeofence()`, ou `leaveGeofence()` não pode responder, porque o pacote não contém coordenadas ou a geocerca não existe mais na conta. Veja [Quando uma função de geocerca não fornece resposta](/docs/user/pt-br/guide/account/iot-logic/nodes/geofence-functions.md#when-a-geofence-function-gives-no-answer).
* `geofenceName()` não tem nome para retornar. Veja [O que você recebe de volta](/docs/user/pt-br/guide/account/iot-logic/nodes/geofence-functions.md#what-you-get-back).

Todas essas causas parecem iguais em uma fórmula. Uma fórmula que precisa continuar funcionando deve lidar com o valor vazio, e não com a causa.

## Fórmulas que devem sempre gerar um valor

Proteja o cálculo com `!= null`, e coloque a guarda primeiro. A guarda usa `!=`, o que fornece um sim ou não verdadeiro para um valor vazio, de modo que a própria guarda nunca para:

```jexl
value('Odômetro', 0, 'all') != null && value('Odômetro', 0, 'all') > 100
```

A ordem é o que faz a cláusula de guarda funcionar. Se você inverter os termos, a comparação é executada antes da cláusula de guarda, e a condição inteira não produz nada.

Para usar um valor de fallback em vez disso, use `??`. Ele retorna o lado direito somente quando o lado esquerdo está vazio:

```jexl
can_speed ?? 0
```

`??` substitui um valor ausente, não um cálculo falho. `(can_speed * 1.1) ?? 0` não produz nada quando `can_speed` está ausente, porque a multiplicação para antes de `??` ser alcançada. Coloque `??` em torno do atributo em vez de em torno do cálculo:

```jexl
(can_speed ?? 0) * 1.1
```

{% hint style="warning" %}
`?:` Webhook `??` parecem semelhantes e se comportam de forma diferente. `??` substitui o lado direito apenas por um valor vazio. `?:` substitui-o por um valor vazio e também por `falso`, por `0`, e para texto vazio. A fórmula `Ignição ?: true` portanto, Relatórios `true` quando a Ignição estiver realmente desligada. Use `??` quando você quer dizer "se o valor estiver ausente".
{% endhint %}

Você também pode condicionar o cálculo de fora da fórmula. Coloque um **Lógica** nó antes do **Iniciar Atributo** nó e teste os atributos quanto à presença em sua condição. Conecte o caminho THEN ao nó de cálculo, para que ele receba apenas os pacotes que contenham os valores de que precisa.

Conecte o caminho ELSE a um **Ponto de Extremidade de Saída** Nó também. Um ramo que termina sem um Nó descarta todos os pacotes que chegam a ele, então os pacotes que falharam no teste de presença nunca saem do fluxo.

Quando nenhum valor é melhor do que um incorreto, um atributo sem valor é o resultado correto. Adicione um valor de fallback somente quando um sistema mais adiante no fluxo precisar de um valor em cada pacote.

## Verifique se uma expressão não produz nada

Trabalhe com o que você pode ver em [Analisador de dados](/docs/user/pt-br/guide/account/iot-logic/data-stream-analyzer.md):

1. Selecione o fluxo, depois o dispositivo GPS e o atributo calculado.
2. Desative a **Excluir nulo** alternância. Um cálculo com falha aparece como um `null` valor. A alternância oculta esses valores quando está ativada.
3. Aumente a profundidade se o pacote que você está procurando for mais antigo que os valores na tela.
4. Compare o atributo com os atributos que sua fórmula lê. Um pacote em que as entradas da fórmula têm valores e o atributo calculado é `null` aponta para a fórmula.
5. Verifique cada operador na fórmula em relação a [Como cada operador lida com um valor vazio](#how-each-operator-handles-an-empty-value).
6. Reescreva cada parte que possa estar vazia. Use `== true`, `== false`, ou uma `??` alternativa.

{% hint style="warning" %}
Quando **Excluir nulo** estiver ativado, o último valor que a fórmula produziu permanece na tela com seu próprio timestamp mais antigo. A leitura parece atual, mas pertence a um pacote anterior. Desative o botão de alternância antes de avaliar se IoT Logic ainda calcula um atributo.
{% endhint %}

## Perguntas frequentes

#### Um valor vazio é o mesmo que `falso`?

Não. Uma condição que esteja realmente `falso` armazena `falso`, e uma condição que não pôde ser avaliada armazena um valor vazio. Ambas enviam os dados pela conexão ELSE de um **Lógica** Nó, então o ramo sozinho não informa o que aconteceu. Uma expressão posterior que testa o atributo com `my_flag == false` corresponde apenas ao primeiro caso.

#### Por que um dispositivo GPS deixou de corresponder a uma condição que ainda funciona para os outros?

Dispositivos de modelos diferentes nem sempre enviam os mesmos atributos, e um dispositivo pode parar de reportar um atributo que os outros ainda enviam. Uma condição que lê esse atributo sem uma comparação então não produz nada apenas para esse dispositivo. Compare explicitamente cada termo com `== true` <https://api.eu.navixy.com/v2/>... `== false`.

## Veja também

* [Expressões e sintaxe da Lógica](/docs/user/pt-br/guide/account/iot-logic/nodes/logic-node/logic-node-expressions-and-syntax.md#missing-values-and-null-routing) para qual ramo um Nó de lógica vai e o que ele armazena.
* [Funções de geocerca](/docs/user/pt-br/guide/account/iot-logic/nodes/geofence-functions.md) para os casos em que uma função de Geocerca não consegue responder.
* [Gerenciar atributos](/docs/user/pt-br/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#expression-language) para o `value()` função e as duas opções de sintaxe.
* [Exemplos de cálculo](/docs/user/pt-br/guide/account/iot-logic/nodes/initiate-attribute-node/calculation-examples.md) para exemplos de fórmula.


---

# 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://navixy.com/docs/user/pt-br/guide/account/iot-logic/nodes/missing-values-in-expressions.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.
