> 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/ru/guide/account/iot-logic/nodes/logic-node/logic-node-expressions-and-syntax.md).

# выражения и синтаксис IF/THEN Логика

Пишите выражения IF/THEN Логика, используя основанный на JEXL язык выражений Navixy. Выражения направляют данные, оцениваясь как true или false, хотя отсутствующее значение может вести себя иначе.

## Основы выражений

Узел IF/THEN Логика использует JEXL [язык выражений Navixy IoT Logic](/docs/iot-logic-api/technologies/navixy-iot-logic-expression-language.md), основанный на Java Expression Language (JEXL). Выражения должны возвращать `true` или `false`, но отсутствующее значение не всегда следует этому правилу. Некоторые операторы направляют отсутствующее значение в THEN вместо ELSE, а некоторые оставляют сохранённый атрибут `null` вместо `false`. См. [Отсутствующие значения и маршрутизация null](#missing-values-and-null-routing) перед тем как полагаться на безопасный отказ сравнения.

**Вычисление выражений**: Выражения вычисляются слева направо, а для управления порядком операций можно использовать скобки.

**Пример базового синтаксиса**:

```jexl
condition1 && (condition2 || condition3 > condition4)
```

## Доступные операторы

### Операторы сравнения

<table><thead><tr><th width="138.54547119140625">Оператор</th><th>Описание</th></tr></thead><tbody><tr><td><code>==</code></td><td>Проверяет, равны ли два операнда. Если операнды разных типов, JEXL преобразует их к одному типу, если это возможно</td></tr><tr><td><code>!=</code></td><td>Проверяет, не равны ли два операнда. Возвращает true, если операнды не равны</td></tr><tr><td><code>&#x3C;</code></td><td>Проверяет, что левый операнд меньше правого операнда</td></tr><tr><td><code>&#x3C;=</code></td><td>Проверяет, что левый операнд меньше или равен правому операнду</td></tr><tr><td><code>></code></td><td>Проверяет, что левый операнд больше правого операнда</td></tr><tr><td><code>>=</code></td><td>Проверяет, что левый операнд больше или равен правому операнду</td></tr></tbody></table>

О том, как отсутствующие значения влияют на маршрутизацию, см. [Отсутствующие значения и маршрутизация null](#missing-values-and-null-routing).

### Логические операторы

<table><thead><tr><th width="139.45458984375">Оператор</th><th>Описание</th></tr></thead><tbody><tr><td><code>&#x26;&#x26;</code> или <code>и</code></td><td>Логическое И — проверяет, истинны ли два условия. Возвращает true, если оба условия истинны</td></tr><tr><td><code>||</code> или <code>или</code></td><td>Логическое ИЛИ — проверяет, истинно ли хотя бы одно из двух условий</td></tr><tr><td><code>!</code> или <code>не</code></td><td>Логическое НЕ — преобразует результат условия в противоположное значение</td></tr></tbody></table>

### Операторы сопоставления с шаблоном

<table><thead><tr><th width="138.54547119140625">Оператор</th><th>Описание</th></tr></thead><tbody><tr><td><code>=~</code></td><td>Проверяет, входит ли значение левого операнда в множество правого операнда. Для строк проверяет совпадение с шаблоном регулярного выражения</td></tr><tr><td><code>!~</code></td><td>Проверяет, не входит ли значение левого операнда в множество правого операнда. Для строк проверяет несовпадение с шаблоном регулярного выражения</td></tr><tr><td><code>=^</code></td><td>Проверяет, начинается ли левый строковый операнд с правого строкового операнда</td></tr><tr><td><code>!^</code></td><td>Проверяет, не начинается ли левый строковый операнд с правого строкового операнда</td></tr><tr><td><code>=$</code></td><td>Проверяет, заканчивается ли левый строковый операнд правым строковым операндом</td></tr><tr><td><code>!$</code></td><td>Проверяет, не заканчивается ли левый строковый операнд правым строковым операндом</td></tr></tbody></table>

### Функции зон

Три функции определяют положение устройства относительно заданной Зоны Navixy, а четвёртая возвращает название Зоны, в которой находится устройство. Инструкции по использованию и примеры см. [Функции зон](/docs/user/ru/guide/account/iot-logic/nodes/geofence-functions.md).

<table><thead><tr><th width="194">Функция</th><th width="137">Параметр</th><th>Возвращает true, когда</th></tr></thead><tbody><tr><td><code>inGeofence(id)</code></td><td>ID Зоны</td><td>Устройство сейчас находится внутри Зоны</td></tr><tr><td><code>enterGeofence(id)</code></td><td>ID Зоны</td><td>Устройство только что вошло в зону</td></tr><tr><td><code>leaveGeofence(id)</code></td><td>ID Зоны</td><td>Устройство только что вышло из зоны</td></tr></tbody></table>

**Текущее положение:**

```jexl
inGeofence(35229 /* Зона доставки #4 */)
```

Название Зоны отображается в виде комментария для удобства чтения и не влияет на вычисление. Селектор Зоны автоматически вставляет этот формат.

**Историческое положение:**

```jexl
inGeofence(35229 /* Зона доставки № 4 */, 1, 'valid')
```

Второй параметр — индекс пакета данных (0 для текущего, 1 для предыдущего, до 11), а третий — фильтр валидности, по той же схеме, что и `value()`. Оба параметра необязательны и применяются к `inGeofence()` только. `enterGeofence()` и `leaveGeofence()` принимайте только ID Зоны и ничего более. Не оборачивайте функцию Зоны внутри `value()`: первый параметр `value()` — это имя атрибута, а не выражение.

## Примеры выражений

<details>

<summary>Примеры базовых условий</summary>

**Проверки на равенство**:

```
value('lock_state', 0, 'valid') == 'sealed'
door_state_2 == 0
```

**Проверки на неравенство**:

```
value('lock_state', 1, 'valid') != 'unknown'
avl_io_221 != null
```

**Предостережение о пропущенном значении**: `!=` Проверка на литерал, отличный от null, направляет пропущенные значения в THEN, а не в ELSE.

Безопасно: проверка наличия ограничивает проверку пакетами, которые содержат этот атрибут.

```
value('temperature', 0, 'all') != null && value('temperature', 0, 'all') > 50
```

Небезопасно: это срабатывает на `temperature`'s первых пакетах до того, как у него появится какая-либо история, поскольку `!=` считает пропущенное значение неравным любому литералу.

```
value('temperature', 1, 'all') != 75
```

**Числовые сравнения**:

```
value('humidity', 1, 'all') < 80
value('humidity', 1, 'all') <= 80
value('humidity', 0, 'valid') > 80
value('humidity', 0, 'valid') >= 80
```

**Мониторинг температуры**:

```
value('temperature', 0, 'valid') > 75
```

Это выражение срабатывает, когда температура превышает 75 градусов, что полезно для Контроль событий при перегреве.

**Обнаружение Контроль скорости**:

```
value('speed', 0, 'valid') > 80
```

Это выражение определяет, когда Транспорт превышает ограничения скорости 80 км/ч.

**Мониторинг состояния устройства**:

```
value('battery_voltage', 0, 'valid') < 11.5
```

Это выражение обнаруживает состояния «Низкий заряд батареи», требующие внимания при «Техобслуживание».

**Контроль событий уровня топлива**:

```
value('fuel_level', 0, 'valid') < 20
```

Это выражение определяет, когда уровень топлива опускается ниже 20 %, что позволяет заранее выполнить дозаправку.

</details>

<details>

<summary>Примеры логических операторов</summary>

**операции AND**:

```
value('temperature', 0, 'valid') > 15 && value('humidity', 0, 'valid') > 80
value('temperature', 0, 'valid') > 15 and value('humidity', 0, 'valid') > 80
```

**Операции OR**:

```
temperature < 10 || humidity > 80
temperature < 10 or humidity > 80
```

**Операции NOT**:

```
!condition
not condition
```

</details>

<details>

<summary>Примеры сопоставления с шаблоном</summary>

**Принадлежность множеству**:

```
value('lock_state', 0, 'valid') =~ ['locked','unlocked']
value('driver_name', 0, 'valid') !~ ['John', 'Steve']
```

**Сопоставление строк по шаблону**:

```
водитель_id =^ 'cc6f8216'
водитель_id !^ 'cc6f8216'
value('engine_hours', 0, 'valid') =$ '1000'
value('driver_id', 0, 'valid') !$ '8b38851c3c68'
```

</details>

<details>

<summary>Сложные примеры с несколькими условиями</summary>

**Оповещение о превышении скорости вне рабочего времени**:

```
value('speed', 0, 'valid') > 60 && (value('current_hour', 0, 'valid') >= 18 || value('current_hour', 0, 'valid') <= 6)
```

Это сочетает мониторинг скорости с условиями, основанными на времени, для усиленного надзора за Безопасность во время ночных смен.

**Комплексная диагностика устройства**:

```
value('gps_satellites', 0, 'valid') >= 4 && value('battery_voltage', 0, 'valid') > 11.5 && value('signal_strength', 0, 'valid') > -80
```

Это одновременно проверяет несколько параметров состояния устройства, чтобы обеспечить надежную работу.

**Мониторинг безопасности водителя**:

```
value('harsh_braking', 0, 'valid') == true && value('driver_identified', 0, 'valid') == false
```

Это позволяет определить небезопасное вождение, когда Водитель не идентифицирован должным образом в системе.

**Планирование техобслуживания оборудования**:

```
value('engine_hours', 0, 'valid') > 250 && value('last_maintenance', 0, 'valid') > 30
```

Это запускает Контроль событий, когда Моточасы превышают пороговые значения, а Техобслуживание просрочено.

**Соответствие диапазону температур**:

```
value('cargo_temperature', 0, 'valid') < -18 || value('cargo_temperature', 0, 'valid') > 4
```

Это определяет, когда температура охлаждённого груза выходит за пределы допустимого диапазона.

</details>

<details>

<summary>Сложность выражений и скобки</summary>

Вы можете создавать сложные выражения, объединяя несколько условий с помощью скобок, чтобы управлять порядком вычисления:

**Комплексная проверка безопасности**:

```
Водитель идентифицирован == false && (вибрация активна == true || скорость > 3)
```

**Многопараметрическая проверка оборудования**:

{% code overflow="wrap" %}

```
(value('oil_pressure', 0, 'valid') < 20 || value('coolant_temp', 0, 'valid') > 95) && value('engine_running', 0, 'valid') == true
```

{% endcode %}

</details>

## Отсутствующие значения и маршрутизация null

**Распространённый симптом:** Условие срабатывает на самых первых пакетах устройства, до того как на него когда-либо поступит атрибут, на который есть ссылка. Обычно это означает, что условие использует `!=` (или отрицательный оператор шаблона) против отсутствующего значения. См. [Операторы сравнения с операндами null](#comparison-operators-with-null-operands) и [Логические операторы с операндами null](#logical-operators-with-null-operands) чтобы понять, какие операторы безопасны по умолчанию, а какие требуют проверки.

На указанный атрибут получается `null` в четырёх случаях:

* Он ни разу не передавался для этого устройства.
* Он отсутствует в текущем пакете, но в более раннем пакете по-прежнему есть значение.
* Запрошенный индекс истории ещё не существует.
* Устройство не передавало ничего более 30 дней, поэтому Navixy удалил сохранённую историю.

JEXL обрабатывает все четыре одинаково, как `null`, поэтому поведение оператора при отсутствии значения не зависит от того, какой из этих четырёх случаев его вызвал. Атрибут, который ни разу не отправлялся, не приводит к ошибке потока. О 30-дневном хранении сохранённых значений см. [Полный синтаксис](/docs/user/ru/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#full-syntax).

О том, почему отсутствующее значение останавливает выражение, и о шаблонах сравнения, которые предотвращают это в обоих типах узлов, см. [Отсутствующие значения в выражениях](/docs/user/ru/guide/account/iot-logic/nodes/missing-values-in-expressions.md).

Каждое входящее сообщение покидает узел Logic через ровно одну ветвь — THEN или ELSE — даже если условие ссылается на отсутствующие данные. Если общий результат условия отличается от `true` (включая `null`, или значение, которое узел не может вычислить), сообщение направляется в ELSE. Следовательно, ветвь ELSE содержит как «условие ложно», так и «условие не удалось выполнить на основе доступных данных».

### Null-безопасные шаблоны условий

**Проверка наличия** (рекомендуется, когда условие должно применяться только к пакетам, содержащим этот атрибут). Сохранённый атрибут — это реальный `true`/`false` здесь, а не `null`:

```jexl
value('temperature', 0, 'all') != null && value('temperature', 0, 'all') > 50
```

**Явная проверка отсутствия данных**: `null` В условиях допускаются литералы.

```jexl
value('attribute', 0, 'all') == null
```

**`||` упорядочивание цепочки**: Поместите выражение, которое может быть null, последним. Упорядочивание помогает только в пакетах, где левый операнд истинный, поэтому считайте это улучшением, а не исправлением.

Небезопасно: левый операнд со значением null переходит в ELSE, хотя `speed > 50` истинно для того же пакета.

```jexl
value('attribute', 0, 'all') > 5 || value('speed', 0, 'all') > 50
```

Лучше: при истинном левом операнде вычисление прерывается до оценки правого операнда, равного null. В пакете, где скорость равна 20, правый операнд, равный null, всё равно вычисляется, и условие по-прежнему переходит в ELSE.

```jexl
value('speed', 0, 'all') > 50 || value('attribute', 0, 'all') > 5
```

Для формы, которая работает с каждым пакетом, сравнивайте каждый термин явно. См. [Явное сравнение значения](/docs/user/ru/guide/account/iot-logic/nodes/missing-values-in-expressions.md#compare-a-value-explicitly).

**Не полагайтесь на `!()` для обнаружения отсутствующих данных**: Когда `x` равен null, оба `x > 5` и `!(x > 5)` переходят в ELSE.

**`'все'` против `'действительный'`**: `value(attr, 0, 'valid')` может возвращать последнее ненулевое значение из более раннего пакета. Условие по-прежнему может вычисляться по реальному значению, даже если в текущем пакете оно отсутствует. Используйте `'все'` когда условие должно отражать только текущий пакет.

### Операторы сравнения с операндами null

| Ситуация                                                                                  | Переходит в | Сохраненное значение атрибута |
| ----------------------------------------------------------------------------------------- | ----------- | ----------------------------- |
| `<`, `<=`, `>`, или `>=` при отсутствии значения                                          | ELSE        | `null`                        |
| `!=` при отсутствии значения и ненулевом литерале (например, `value('a', 0, 'all') != 1`) | THEN        | `true`                        |
| `==` при отсутствии значения и ненулевом литерале                                         | ELSE        | `false`                       |
| `проверку == null` при отсутствии значения                                                | THEN        | `true`                        |
| `!= null` когда атрибут отсутствует                                                       | ELSE        | `false`                       |
| `!= null` когда атрибут присутствует                                                      | THEN        | `true`                        |
| `=~` при отсутствии значения и строковом литерале или списке                              | ELSE        | `false`                       |
| `!~` при отсутствии значения и строковом литерале или списке                              | THEN        | `true`                        |
| `=^` или `=$` при отсутствии `value()` результат                                          | ELSE        | `false`                       |
| `!^` или `!$` при отсутствии `value()` результат                                          | THEN        | `true`                        |
| `=^`, `!^`, `=$`, или `!$` при отсутствии атрибута, на который ссылаются по имени         | ELSE        | `null`                        |

{% hint style="warning" %}
`!=` при отсутствии значения и ненулевом литерале оценивается как `true` и переходит в THEN. Условие вида `value('attribute', 1, 'all') != 1` может сработать на первых пакетах устройства, еще до того, как у этого атрибута появится история. Это может произойти даже тогда, когда предполагается направлять неизвестные значения в ELSE.

Чтобы безопасно завершать с ошибкой, когда значение еще может отсутствовать, используйте проверку наличия или явную `проверку == null` проверку:

```jexl
value('attribute', 1, 'all') != null && value('attribute', 1, 'all') != 1
```

`null == null` — это `true`, и `null != null` — это `false`. Проверка наличия проверяет, есть ли значение у атрибута в этом пакете, а не отличается ли оно от литерала.
{% endhint %}

{% hint style="warning" %}
`=~` и `!~` сводятся к реальному `true` или `false` при отсутствии значения, какой бы синтаксис вы ни использовали. При отсутствии значения, `=~` считается «не совпадает» и попадает в ELSE, а `!~` попадает в THEN.

Операторы starts-with и ends-with (`=^`, `!^`, `=$`, `!$`) — это единственное место, где эти два варианта синтаксиса различаются. С `value()`, они ведут себя как `=~` и `!~`: `value('a', 0, 'all') =^ 'AB'` сводится к `false` и попадает в ELSE, а `!^` сводится к `true` и попадает в THEN. Если атрибут указан по имени, `a =^ 'AB'` сводится к `null` вместо этого, и положительная, и отрицательная формы попадают в ELSE.

Краткая форма — это то, [автозаполнение](/docs/user/ru/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#autofill-attribute-names) что вставляет селектор атрибутов, поэтому условие, построенное с помощью селектора атрибутов, идет по второму пути. Запишите сравнение с `value()` когда вам нужно `!^` или `!$` срабатывать на пакете, который не содержит атрибута.

`!~` попадание в THEN — это другой механизм, чем `!=` попадание в THEN. `!~` попадает туда, потому что отсутствующее значение считается «не совпадающим», и `!=` попадает туда, потому что отсутствующее значение «не равно» литералу. Не думайте, что одно объясняет другое.
{% endhint %}

### Логические операторы с операндами null

| Ситуация                                                                                    | Переходит в | Сохраненное значение атрибута                                           |
| ------------------------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- |
| `!(x > 5)` когда `x` отсутствует                                                            | ELSE        | `null`                                                                  |
| Нулевой операнд в \`                                                                        |             | \` вычисляется раньше истинного операнда в том же пакете                |
| Истинный операнд в \`                                                                       |             | \` вычисляется раньше нулевого операнда (происходит короткое замыкание) |
| Нулевой операнд в `&&` с истинным операндом, в любом порядке                                | ELSE        | `null`                                                                  |
| `false` операнд в `&&` вычисляется раньше нулевого операнда (происходит короткое замыкание) | ELSE        | `false`                                                                 |
| `false` операнд в \`                                                                        |             | \` вычисляется раньше нулевого операнда                                 |

Порядок важен для обоих операторов. Каждый из них сначала вычисляет левый операнд и останавливается на нем, если левый операнд уже определяет результат. Один `false` левый операнд определяет `&&`, а `true` левый операнд определяет `||`. Во всех остальных сочетаниях нулевой операнд вычисляется, условие сводится к `null`, а сообщение направляется в ELSE.

Истинный операнд не может выполнить короткое замыкание мимо нулевого в `&&`, поскольку AND все еще должен знать, провалит ли нулевая сторона условие. Один `false` операнд может, и узел тогда сохраняет реальный `false` вместо `null`. Для того же правила, примененного к формулам атрибутов, и для шаблонов сравнения, которые его обходят, см. [Отсутствующие значения в выражениях](/docs/user/ru/guide/account/iot-logic/nodes/missing-values-in-expressions.md).

## Сценарии обработки ошибок

| Сценарий                                                                              | Результат             | Путь потока     | Значение атрибута |
| ------------------------------------------------------------------------------------- | --------------------- | --------------- | ----------------- |
| Выражение вычисляется в `true`                                                        | Успех                 | Соединение THEN | `true`            |
| Выражение вычисляется в `false`                                                       | Успех                 | Соединение ELSE | `false`           |
| Атрибут, на который ссылаются `null` и используется отдельно, без оператора сравнения | Сводится к `null`     | Соединение ELSE | `null`            |
| Отсутствующее значение, сравниваемое с `<`, `<=`, `>`, или `>=`                       | Сводится к `null`     | Соединение ELSE | `null`            |
| Отсутствующее значение, сравниваемое с `==` и не являющимся литералом значением       | Вычисляется в `false` | Соединение ELSE | `false`           |
| Отсутствующее значение, сравниваемое с `проверку == null`                             | Вычисляется в `true`  | Соединение THEN | `true`            |
| Отсутствующее значение, сравниваемое с `!=` и не являющимся литералом значением       | Вычисляется в `true`  | Соединение THEN | `true`            |
| Синтаксическая ошибка в выражении                                                     | Сводится к `null`     | Соединение ELSE | `null`            |

{% hint style="warning" %}
Строка, которая уходит в ELSE, не всегда означает, что атрибут хранится как `false`. Пустая ссылка null и операторы сравнения (`<`, `<=`, `>`, `>=`) уводят в ELSE, но сохраняют атрибут как `null`. Последующее выражение, которое проверяет атрибут напрямую (`my_flag == false` или `my_flag == 0`) нуждается в null-безопасной проверке, чтобы поймать этот случай, поскольку оно не совпадет с `null` значением.

В **Вычисление атрибута** На узле те же сбои вместо этого оставляют атрибут вне исходящего пакета данных. См. [Отсутствующие значения в выражениях](/docs/user/ru/guide/account/iot-logic/nodes/missing-values-in-expressions.md).
{% endhint %}

## Практические примеры реализации

<details>

<summary>Мониторинг температуры автопарка</summary>

**Бизнес-требование**: Контролируйте рефрижераторный транспорт, чтобы обеспечить соблюдение температурного режима груза

```
value('cargo_temperature', 0, 'valid') > 4 || value('cargo_temperature', 0, 'valid') < -18
```

* **ветка THEN**: Немедленно отправляйте оповещения в диспетчерскую, регистрируйте нарушения соответствия, запускайте корректирующие действия
* **ветка ELSE**: Продолжайте обычную обработку для допустимых температур, обновляйте панели состояния

</details>

<details>

<summary>Контроль безопасности водителя</summary>

**Бизнес-требование**: Выявляйте небезопасные модели вождения в активные часы смены

```
value('harsh_acceleration', 0, 'valid') == true && value('shift_active', 0, 'valid') == true
```

* **ветка THEN**: Формируйте отчеты по обучению водителя, отправляйте уведомления безопасности, регистрируйте инциденты
* **ветка ELSE**: Обрабатывайте данные о нормальном вождении, обновляйте показатели эффективности

</details>

<details>

<summary>Предиктивные оповещения о техобслуживании</summary>

**Бизнес-требование**: Обнаруживайте потенциальные отказы оборудования до того, как они произойдут

```
value('engine_temperature', 0, 'valid') > 95 && value('oil_pressure', 0, 'valid') < 30
```

* **ветка THEN**: Планируйте визиты на техобслуживание, отправляйте уведомления технику, регистрируйте диагностические данные
* **ветка ELSE**: Продолжайте плановый мониторинг, обновляйте панели состояния оборудования

</details>

<details>

<summary>Мониторинг соблюдения зоны</summary>

**Бизнес-требование**: Убедитесь, что транспорт работает в разрешенных зонах в рабочее время

```jexl
inGeofence(51577 /* Austin Warehouse */) == true && value('business_hours', 0, 'valid') == true
```

В этом выражении используется `inGeofence()` функция, чтобы проверить, находится ли устройство внутри именованной зоны, в сочетании с атрибутом рабочих часов. Границы зоны настраиваются в интерфейсе зон Navixy, поэтому значения координат не нужно поддерживать в выражении.

Вкладка `== true` Сравнение позволяет условию продолжать работу с пакетами, где функция зоны не может определить решение, например с пакетом, который не содержит позицию. Без этого одно пустое значение останавливает все условие, и сообщение направляется в ELSE.

* **ветка THEN**: Продолжайте обычную работу; устройство находится в разрешенной зоне в рабочие часы.
* **ветка ELSE**: Сгенерируйте оповещение о несанкционированном выезде, уведомите охрану и зафиксируйте нарушение.

Чтобы обнаружить момент, когда транспорт покидает разрешенную зону, а не проверять это непрерывно, используйте `leaveGeofence()` вместо этого:

```jexl
leaveGeofence(51577 /* Склад в Остине */) == true && value('business_hours', 0, 'valid') == true
```

Полное описание функций зоны, включая `enterGeofence()`, `geofenceName()`, и проверку более ранней позиции с помощью `inGeofence()`, см. [Функции зон](/docs/user/ru/guide/account/iot-logic/nodes/geofence-functions.md).

</details>


---

# 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/ru/guide/account/iot-logic/nodes/logic-node/logic-node-expressions-and-syntax.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.
