> 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/fr/guide/account/iot-logic/nodes/missing-values-in-expressions.md).

# Valeurs manquantes dans les expressions

Comprenez pourquoi une formule ou une condition IoT Logic ne produit aucune valeur lorsqu'une valeur dont elle a besoin est absente, et quels modèles de comparaison l'empêchent.

Les formules et les conditions dans IoT Logic s’appuient sur les valeurs qu’un appareil GPS envoie. Lorsqu’une valeur requise par une formule est manquante, la plupart des opérateurs ne peuvent pas produire de résultat, et la formule ne produit rien du tout : ni `faux`, et pas zéro. Cette page explique quand une valeur disparaît, à quoi ressemble l’échec et comment écrire des formules et des conditions qui continuent de fonctionner. Elle s’adresse à toute personne qui configure un flux IoT Logic, et ne suppose aucune connaissance en programmation.

Cette page s’applique aux deux endroits où vous écrivez une expression : le **Formule** champ d’un [Initialiser un Attribut](/docs/user/fr/guide/account/iot-logic/nodes/initiate-attribute-node.md) nœud, et le **Expression de condition (JEXL)** champ d’un [nœud Logique.](/docs/user/fr/guide/account/iot-logic/nodes/logic-node.md) nœud.

## Lorsqu’une expression ne peut pas produire de valeur

Une valeur vide bloque toute l’expression. Cela s’applique de part et d’autre d’un calcul, d’une comparaison de taille, d’un test de préfixe de texte ou d’un opérateur logique `!`, `&&`, ou `||`. Dans une formule et dans Analyseur de données, une valeur vide apparaît comme `null`.

Lire un attribut qu’un appareil GPS n’a jamais envoyé n’est pas une erreur en soi. Ce qui s’arrête, c’est l’opérateur qui doit alors travailler avec la valeur vide. Une seule valeur vide arrête toute l’expression, y compris les parties qui avaient des valeurs. Une condition qui teste quatre zones de géorepérage s’arrête à la première qui ne peut pas répondre, et les trois autres ne sont jamais testées. L’exception est un terme plus tôt dans l’expression qui a déjà fixé le résultat.

## Ce que vous voyez lorsqu’une expression ne produit rien

Rien n’indique l’échec. Le résultat dépend du nœud qui contient l’expression :

| Où l’expression s’exécute                                            | Ce qui se passe pour ce paquet de données                                                                                    |
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Formule** champ d’un **Initialiser un Attribut** nœud              | L’attribut n’a aucune valeur pour ce paquet, et Analyseur de données l’affiche comme `null`.                                 |
| **Expression de condition (JEXL)** champ d’un **nœud Logique.** nœud | Les données sortent par la connexion ELSE, et le nœud stocke son propre attribut comme une valeur vide, et non comme `faux`. |

{% hint style="warning" %}
Rien n’indique l’échec. Aucune erreur n’apparaît dans le flux, aucun compteur ne change, et tous les autres attributs continuent d’être calculés normalement. Le seul signe est la valeur manquante elle-même, si bien qu’un flux peut sembler sain alors qu’un attribut ne produit aucune valeur pendant des semaines.

L’enregistrement d’un flux ne prouve pas non plus qu’une formule fonctionne. La vérification effectuée lors de l’enregistrement confirme que l’expression est écrite correctement. Elle n’exécute pas l’expression sur les données de votre appareil GPS, si bien qu’une formule qui ne produit rien pour chaque paquet s’enregistre quand même sans avertissement.
{% endhint %}

## Comment chaque opérateur gère une valeur vide

Quatre opérateurs continuent toujours de fonctionner sur une valeur vide : `==`, `!=`, `=~`, et `!~`. Les opérateurs `&&` et `||` continuent à fonctionner uniquement lorsque le côté lu en premier fixe la réponse. Tous les autres opérateurs s’arrêtent.

Ce tableau couvre un attribut que vous référencez par son nom, qui est la forme que [remplissage automatique](/docs/user/fr/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#autofill-attribute-names) la formule insère. Quatre opérateurs se comportent différemment lorsque la valeur provient de `value()` à la place. Voir [Lecture par nom ou avec value()](#reading-by-name-or-with-value).

| Opérateur                                                         | Avec une valeur vide de part et d’autre                                                                             |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `==`, `!=` (égal à, différent de)                                 | Renvoie un véritable oui ou non. `null == null` est `true`, et `null != null` est `faux`.                           |
| `=~`, `!~` (est dans une liste ou correspond à un motif de texte) | Renvoie un véritable oui ou non. Une valeur vide ne correspond jamais, donc `=~` donne `faux` et `!~` donne `true`. |
| `??` (utiliser une valeur de repli)                               | Renvoie la valeur de droite. Elle se substitue uniquement à une valeur vide.                                        |
| `?:` (utiliser une valeur de repli)                               | Renvoie la valeur de droite. Elle se substitue aussi à `faux`, à `0`, et au texte vide.                             |
| `a ? b : c` (choisir entre deux valeurs)                          | Prend la `c` branche, comme pour `faux`.                                                                            |
| `=^`, `!^`, `=$`, `!$` (commence par, se termine par)             | L’expression ne produit rien.                                                                                       |
| `<`, `<=`, `>`, `>=` (comparaisons de taille)                     | L’expression ne produit rien.                                                                                       |
| `+`, `-`, `*`, `/`, `%` (arithmétique)                            | L’expression ne produit rien.                                                                                       |
| `&`, `\|`, `^` (opérations sur les bits)                          | L’expression ne produit rien.                                                                                       |
| `!` (non)                                                         | L’expression ne produit rien.                                                                                       |
| `&&`, `\|\|` (et, ou)                                             | L’expression ne produit rien, sauf si le côté lu en premier fixe la réponse.                                        |

Les six opérateurs de texte se divisent en deux. `=~` et `!~` survivent à une valeur vide, mais `=^`, `!^`, `=$`, et `!$` ne le font pas lorsque l’attribut est référencé par son nom. Une condition telle que `hardware_key !^ 'AB'` semble être un moyen sûr d’exclure un préfixe, mais il ne produit rien sur chaque paquet sans `hardware_key`.

Le `math:` les fonctions ne produisent rien lorsqu’elles reçoivent une valeur vide, donc `math:round(engine_temp)` ne produit rien lorsque `engine_temp` est manquant. Le `util:` les fonctions sont plus tolérantes et renvoient une valeur vide à la place, donc `util:join` et `util:joinNonNull` elles produisent toujours un résultat lorsqu’un de leurs arguments est manquant. La concaténation de texte avec `+` n’est pas tolérante : `'Zone: ' + zone_label` ne produit rien.

## Opérateurs logiques avec une valeur vide

L’ordre compte pour les deux `&&` et `||`. Chaque opérateur lit d’abord le côté gauche et s’arrête là lorsque le côté gauche suffit déjà à déterminer le résultat. Un `faux` le côté gauche suffit à déterminer `&&`, et un `true` le côté gauche suffit à déterminer `||`.

| Expression                   | Résultat                                                                                           |
| ---------------------------- | -------------------------------------------------------------------------------------------------- |
| `faux && (vide)`             | `faux`. Un côté gauche faux suffit à déterminer AND, donc le côté droit n’est jamais lu.           |
| `vrai && (vide)`             | Ne produit rien.                                                                                   |
| `(vide) && n’importe quoi`   | Ne produit rien. Le côté gauche est lu en premier.                                                 |
| `vrai \|\| (vide)`           | `true`. Un opérande gauche vrai suffit pour OR, de sorte que l’opérande droit n’est jamais évalué. |
| `false \|\| (vide)`          | Ne produit rien.                                                                                   |
| `(vide) \|\| n'importe quoi` | Ne produit rien. Le côté gauche est lu en premier.                                                 |

Placer en dernier le terme qui pourrait être vide n’est utile que lorsque le côté gauche fixe le résultat sur ce paquet. Vous pouvez rarement garantir ce résultat, comparez donc explicitement la valeur à la place.

## Lecture par nom ou avec value()

Quatre opérateurs donnent des résultats différents pour la même valeur manquante, selon la façon dont la formule l’interprète. Les opérateurs sont `=^`, `!^`, `=$` et `!$`, ceux qui testent le début ou la fin d’une valeur de texte.

| Formule                                | Résultat lorsque `conducteur_id` n’a jamais été envoyé |
| -------------------------------------- | ------------------------------------------------------ |
| `Conducteur_id !^ 'AB'`                | Ne produit rien                                        |
| `value('driver_id', 0, 'all') !^ 'AB'` | `true`                                                 |

Référencer l’attribut par son nom est le Formulaire qui [remplissage automatique](/docs/user/fr/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#autofill-attribute-names) insérés, donc une condition construite avec le sélecteur d’attributs prend le premier chemin. Écrivez la comparaison avec `value()` lorsque vous devez `!^` ou `!$` signaler `true` sur un paquet qui ne porte pas l’attribut.

Tous les autres opérateurs se comportent de la même manière dans les deux formes. Une comparaison de taille, des opérations arithmétiques et `!` tous ne produisent rien dans un cas comme dans l’autre, et `==`, `!=`, `=~` et `!~` tous donnent un vrai oui ou non dans un sens ou dans l'autre.

La même répartition s’applique aux deux formulaires de repli. `??` et `? :` peut contenir un calcul ayant échoué lorsque la valeur provient de `value()`, et ne le peut pas lorsqu'elle provient d'un nom :

| Formule                                               | Résultat lorsque `compteur kilométrique` n’a jamais été envoyé |
| ----------------------------------------------------- | -------------------------------------------------------------- |
| `(compteur kilométrique + 1) ?? 0`                    | Ne produit rien                                                |
| `(value('Compteur kilométrique', 0, 'all') + 1) ?? 0` | `0`                                                            |

Une simple `??` sur un nom fonctionne toujours, car aucun calcul n’a lieu avant. Seul un calcul encapsulé dans `??` ou `? :` se comporte différemment.

## Comparer explicitement une valeur

Pour sécuriser une valeur qui peut être vide dans une condition, comparez-la à `== true` ou `== false` au lieu de l'utiliser seule. Les deux `==` et `!=` donnez un vrai oui ou non pour une valeur vide, afin qu’un terme sans donnée n’interrompe plus toute la condition.

Cette condition s’arrête sur n’importe quel paquet où l’un des deux attributs est manquant :

```jexl
door_open || hood_open
```

Cette condition continue de fonctionner et renvoie oui lorsque l’une des deux portes est ouverte :

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

Les fonctions de zone géographique se comportent de la même façon, car elles renvoient une valeur vide lorsqu’un paquet ne contient aucune position. Cette condition s’arrête dès qu’une fonction ne peut pas répondre :

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

Cette condition teste les deux zones géographiques sur chaque paquet :

```jexl
leaveGeofence(51577 /* Entrepôt d’Austin */) == true || leaveGeofence(85269 /* Chantier de construction 1 */) == true
```

Choisissez la comparaison qui correspond à ce qu’un paquet sans donnée doit compter comme :

* `== true` signifie « considéré comme oui ». Une valeur vide donne `faux`, donc un paquet sans données ne correspond pas.
* `== false` signifie « connu pour être non ». Une valeur vide donne `faux`, donc un paquet sans données ne correspond pas.
* `!= true` signifie « non connu pour être oui ». Une valeur vide donne `true`, donc un paquet sans données correspond.

{% hint style="warning" %}
N'utilisez pas `!` sur une valeur qui pourrait être vide. `!inZone géographique(35229)` ne produit rien lorsque la position est inconnue, donc il ne peut pas détecter un appareil en dehors de la Zone géographique. Écrivez `inZone géographique(35229) == false` pour « connu comme étant à l'extérieur », ou `inGeofence(35229) != true` pour « non connu comme étant à l'intérieur ».
{% endhint %}

## D'où viennent les valeurs vides

Un attribut dans une formule prend la valeur vide dans les cas suivants :

* L'attribut n'a jamais été envoyé pour cet appareil GPS.
* Le paquet actuel ne contient pas l'attribut, bien qu'un paquet précédent l'ait fait.
* La position d'historique que vous avez demandée avec `value()` n'existe pas encore, car l'appareil a envoyé moins de paquets que la position n'en exige.
* L'appareil n'a rien envoyé pendant plus de 30 jours, donc Navixy a supprimé son historique stocké. Voir [Syntaxe complète](/docs/user/fr/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#full-syntax).
* `inGeofence()`, `enterGeofence()`, ou `leaveGeofence()` Impossible de répondre, car le paquet ne contient aucune coordonnée ou la Zone géographique n’existe plus dans le compte. Voir [Quand une fonction de zone géographique ne donne pas de réponse](/docs/user/fr/guide/account/iot-logic/nodes/geofence-functions.md#when-a-geofence-function-gives-no-answer).
* `geofenceName()` n’a aucun nom à renvoyer. Voir [Ce que vous obtenez en retour](/docs/user/fr/guide/account/iot-logic/nodes/geofence-functions.md#what-you-get-back).

Toutes ces causes se présentent de la même manière dans une formule. Une formule qui doit continuer à fonctionner doit gérer la valeur vide plutôt que la cause.

## Formules qui doivent toujours renvoyer une valeur

Protégez le calcul avec `!= null`, et placez d'abord la garde. La garde utilise `!=`, ce qui donne un vrai oui ou non pour une valeur vide, de sorte que la garde elle-même ne s’arrête jamais :

```jexl
value('Compteur kilométrique', 0, 'all') != null && value('Compteur kilométrique', 0, 'all') > 100
```

L’ordre est ce qui fait fonctionner la garde. Si vous inversez les termes, la comparaison s’exécute avant la garde, et l’ensemble de la condition ne produit rien.

Pour substituer une valeur de repli à la place, utilisez `??`. Elle renvoie le côté droit uniquement lorsque le côté gauche est vide :

```jexl
can_speed ?? 0
```

`??` substitue une valeur manquante, et non un calcul échoué. `(can_speed * 1.1) ?? 0` ne produit rien lorsque `can_speed` est manquant, car la multiplication s’arrête avant `??` est atteinte. Placez `??` autour de l’attribut plutôt qu’autour du calcul :

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

{% hint style="warning" %}
`?:` et `??` se ressemblent et se comportent différemment. `??` substitue le côté droit uniquement pour une valeur vide. `?:` le remplace par une valeur vide et aussi pour `faux`, à `0`, et pour un texte vide. La formule `contact ?: true` indique donc `true` quand le contact est réellement coupé. Utilisez `??` lorsque vous voulez dire « si la valeur est absente ».
{% endhint %}

Vous pouvez également conditionner le calcul depuis l'extérieur de la formule. Placez un **nœud Logique.** nœud avant le **Initialiser un Attribut** nœud, et vérifiez la présence des attributs dans sa condition. Connectez le chemin THEN au nœud de calcul, afin qu'il reçoive uniquement les paquets qui contiennent les valeurs dont il a besoin.

Reliez le chemin ELSE à un **nœud Point de sortie** nœud également. Une branche qui se termine sans nœud élimine chaque paquet qui l’atteint, donc les paquets ayant échoué au test de présence ne quittent jamais le flux.

Quand aucune valeur n’est préférable à une valeur erronée, un attribut sans valeur est le résultat correct. Ajoutez une solution de repli uniquement lorsqu’un système en aval du flux a besoin d’une valeur pour chaque paquet.

## Vérifiez si une expression ne produit rien

Travaillez à partir de ce que vous pouvez voir dans [Analyseur de données](/docs/user/fr/guide/account/iot-logic/data-stream-analyzer.md):

1. Sélectionnez le flux, puis le périphérique GPS et l’attribut calculé.
2. Désactivez le **Exclure les valeurs nulles** bouton bascule. Un calcul échoué apparaît sous forme de `null` valeur. Le bouton bascule masque ces valeurs lorsqu’il est activé.
3. Augmentez la profondeur si le paquet que vous recherchez est plus ancien que les valeurs affichées à l’écran.
4. Comparez l’attribut avec les attributs que lit sa formule. Un paquet où les entrées de la formule ont des valeurs et où l’attribut calculé est `null` pointe vers la formule.
5. Vérifiez chaque opérateur de la formule par rapport à [Comment chaque opérateur gère une valeur vide](#how-each-operator-handles-an-empty-value).
6. Réécrivez chaque partie qui peut être vide. Utilisez `== true`, `== false`, ou un `??` plan de repli.

{% hint style="warning" %}
Lorsque **Exclure les valeurs nulles** est activé, la dernière valeur produite par la formule reste affichée à l’écran avec son propre horodatage plus ancien. La lecture semble actuelle, mais elle appartient à un paquet antérieur. Désactivez le commutateur avant de juger si IoT Logic calcule encore un attribut.
{% endhint %}

## Foire aux questions

#### Une valeur vide est-elle la même que `faux`?

Non. Une condition qui est réellement `faux` stocke `faux`, et une condition qui n’a pas pu être évaluée stocke une valeur vide. Les deux envoient les données via la connexion ELSE d’un **nœud Logique.** Nœud, donc la branche seule ne vous indique pas ce qui s’est produit. Une expression ultérieure qui teste l’attribut avec `my_flag == false` ne correspond qu’au premier cas.

#### Pourquoi un appareil GPS a-t-il cessé de correspondre à une condition qui fonctionne toujours pour les autres ?

Les appareils de modèles différents n’envoient pas tous les mêmes attributs, et un appareil peut cesser de signaler un attribut que les autres envoient encore. Une condition qui lit cet attribut sans comparaison ne produit alors rien pour ce seul appareil. Comparez chaque terme explicitement avec `== true` ou `== false`.

## Voir aussi

* [Expressions et syntaxe de Logique](/docs/user/fr/guide/account/iot-logic/nodes/logic-node/logic-node-expressions-and-syntax.md#missing-values-and-null-routing) pour savoir quelle branche un Nœud Logic emprunte et ce qu’il stocke.
* [Fonctions de zone géographique](/docs/user/fr/guide/account/iot-logic/nodes/geofence-functions.md) pour les cas où une fonction de Zone géographique ne peut pas répondre.
* [Gestion des attributs](/docs/user/fr/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#expression-language) pour le `value()` fonction et les deux options de syntaxe.
* [Exemples de calcul](/docs/user/fr/guide/account/iot-logic/nodes/initiate-attribute-node/calculation-examples.md) pour des exemples de formules.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://navixy.com/docs/user/fr/guide/account/iot-logic/nodes/missing-values-in-expressions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
