> 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/geofence-functions.md).

# Функции зон

Используйте уже имеющиеся в Navixy геозоны в потоках IoT Logic, чтобы реагировать, когда устройство входит в область или покидает ее, либо фиксировать, в какой области оно находится.

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

## Какая функция вам нужна

| Если вы хотите                                                                                                      | Используйте                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Действовать по отношению к одной конкретной зоне, когда устройство находится в ней, входит в нее или выходит из нее | `inGeofence()`, `enterGeofence()`, `leaveGeofence()`. См. [Реакция на одну зону](#reacting-to-one-geofence) |
| Узнать, в какой зоне находится устройство, не указывая ее заранее                                                   | `geofenceName()`. См. [Запись текущей зоны](#recording-the-current-geofence)                                |

{% hint style="warning" %}
Перед тем как ссылаться на них в выражениях IoT Logic, вы должны создать зоны в Navixy. Чтобы создать зоны или управлять ими, см. [Зоны](/docs/user/ru/guide/tracking/map-tools/geofences.md).
{% endhint %}

{% hint style="danger" %}
**`geofenceName()` Это платная опция, приобретаемая отдельно.** По умолчанию она отключена для всех аккаунтов, и ваш поставщик услуг включает ее для каждого аккаунта по запросу. Остальные три функции не затронуты и не требуют дополнительной опции.

Чтобы включить ее, обратитесь к своему поставщику услуг. См. [Перед началом работы](#before-you-start).
{% endhint %}

## Реакция на одну зону

Используйте эти три функции, когда вы уже знаете, какая зона важна. Каждая из них для большинства пакетов данных, которые отправляет устройство, отвечает «да» или «нет», поэтому поток может отправить эти данные по одной ветке или по другой. Для некоторых пакетов функция не может ответить и вместо этого возвращает пустое значение. См. [Когда функция зоны не дает ответа](#when-a-geofence-function-gives-no-answer).

| Функция             | Отвечает «да», когда                    |
| ------------------- | --------------------------------------- |
| `inGeofence(id)`    | Устройство сейчас находится внутри зоны |
| `enterGeofence(id)` | Устройство только что вошло в зону      |
| `leaveGeofence(id)` | Устройство только что вышло из зоны     |

Вы добавляете их в условие **IF/THEN Логика** узла. `id` — это числовой идентификатор зоны в вашем аккаунте Navixy, а селектор подставляет его за вас, поэтому вам редко приходится вводить его вручную. См. [Как добавить условие зоны](#how-to-add-a-geofence-condition).

### Когда функция зоны не дает ответа

`inGeofence()`, `enterGeofence()`, и `leaveGeofence()` возвращают пустое значение вместо «да» или «нет», когда не могут ответить. Функция не может ответить в таких случаях:

* Пакет данных не содержит координат. Позиция низкого качества все равно проверяется, поэтому слабый GPS-сигнал дает реальный ответ «да» или «нет».
* Зона была удалена из вашего аккаунта Navixy или стала недоступна после сохранения потока. Если зоны уже нет к моменту сохранения потока, она вместо этого отклоняется при сохранении.

Пустое значение останавливает условие, частью которого оно является. Когда функция составляет все условие целиком, данные идут по пути ELSE. Обычно именно такое маршрутизирование вам и нужно. Когда функция объединена с чем-то еще, пустое значение может остановить все условие, включая те части, у которых были значения. Чтобы остальная часть условия продолжала работать, сравните функцию с `== true`:

```jexl
leaveGeofence(51577 /* Склад в Остине */) == true || leaveGeofence(85269 /* Стройплощадка 1 */) == true
```

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

### Синтаксис

{% tabs %}
{% tab title="Текущая позиция" %}
Это формат, который селектор зон вставляет автоматически. Название зоны отображается в виде комментария для удобства чтения, но не влияет на вычисление.

```jexl
inGeofence(35229 /* Зона доставки № 4 */)
enterGeofence(51577 /* Склад в Остине */)
leaveGeofence(85269 /* Стройплощадка 1 */)
```

{% endtab %}

{% tab title="Историческая позиция" %}
`inGeofence()` принимает еще два параметра, поэтому может проверять более раннюю позицию вместо текущей:

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

Второй параметр указывает, из какого пакета данных брать позицию, отсчитывая назад от текущего. Третий определяет, учитывать ли пакеты без позиции. Оба параметра необязательны и следуют той же схеме, что и у `value()` функции.

`enterGeofence()` и `leaveGeofence()` принимают ID зоны и ничего больше. Обе сравнивают текущую позицию с предыдущей, поэтому выбирать индекс не нужно. Поток, который передает второй параметр любой из этих функций, нельзя сохранить, а в сообщении об ошибке указывается функция.

Укажите индекс в диапазоне от 0 до 11. `inGeofence()` принимает более высокий индекс, сохраняется без ошибки, а затем возвращает пустое значение для каждого пакета.

Не оборачивайте функцию зоны в `value()`. Первый параметр `value()` является именем атрибута, а не выражением, поэтому такой вызов, как `value("inGeofence(35229)", 1, 'valid')` ищет атрибут с таким буквальным именем и всегда возвращает пустое значение.

Для `value()` подробностей о функции см. [Выражения и синтаксис IF/THEN Логика](/docs/user/ru/guide/account/iot-logic/nodes/logic-node/logic-node-expressions-and-syntax.md).
{% endtab %}
{% endtabs %}

### Как добавить условие зоны

Поле выражения в **IF/THEN Логика** панели настройки Узла включает отдельный селектор зоны <img src="https://2388694493-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F446mKak1zDrGv70ahuYZ%2Fuploads%2Fgit-blob-f1ad9487846cd008c17c7a3a86c7f52b4f8d899d%2Fgeofence-picker.png?alt=media" alt="" data-size="line">, отдельно от стандартного [автодополнения атрибутов](/docs/user/ru/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#autofill-attribute-names). В нем перечислены все зоны, настроенные в вашей учетной записи Navixy, сгруппированные по имени и ID.

Чтобы добавить функцию зоны в выражение:

{% stepper %}
{% step %}

#### Откройте конфигурацию узла

Откройте **IF/THEN Логика** узел, щелкнув по нему на холсте.
{% endstep %}

{% step %}

#### Откройте селектор зон

В поле **Условное выражение (JEXL)** , нажмите значок селектора зон, чтобы открыть список зон.

<figure><img src="https://2388694493-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F446mKak1zDrGv70ahuYZ%2Fuploads%2Fgit-blob-4e9a17bca5a836559c33502a97f6c418f3504898%2Fgeofence-picker-list.png?alt=media" alt="Geofence picker list example, with all three options (in, enter, leave geofence)"><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Найдите и выберите зону

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

* `inGeofence` — используйте, когда нужно проверить, находится ли устройство сейчас внутри выбранной зоны.
* `enterGeofence` — используйте, когда нужно определить, что устройство переместилось снаружи выбранной зоны внутрь нее.
* `leaveGeofence` — используйте, когда нужно определить, что устройство переместилось изнутри выбранной зоны наружу.

Селектор вставляет полный вызов функции в позицию курсора в поле выражения.
{% endstep %}

{% step %}

#### При необходимости объедините с другими условиями

Используйте логические операторы, чтобы объединить функцию зоны с другими условиями. См. [Примеры условий](#condition-examples).
{% endstep %}

{% step %}

#### Сохраните конфигурацию

Нажмите **Примените изменения** чтобы подтвердить конфигурацию узла.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Селектор зон показывает только те зоны, которые существуют в вашей учетной записи Navixy на момент открытия узла. Если вы добавите новую зону после открытия узла, закройте и снова откройте его, чтобы обновить список.
{% endhint %}

Селектор вставляет только три функции, основанные на ID. Чтобы использовать `geofenceName()`, введите его в поле вручную.

### Примеры условий

<details>

<summary>Условие по одной зоне</summary>

Данные маршрута в зависимости от того, находится ли устройство сейчас внутри зоны доставки:

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

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

</details>

<details>

<summary>Обнаружение въезда</summary>

Запустите действие, когда транспортное средство въезжает на ограниченный объект:

```jexl
enterGeofence(85269 /* Construction site 1 */)
```

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

</details>

<details>

<summary>Обнаружение выезда</summary>

Определите, когда транспортное средство покидает разрешенную сервисную зону в рабочее время:

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

* **Ветка THEN**: Отправьте оповещение через **Вебхук** узел в диспетчерскую систему.
* **Ветка ELSE**: Продолжайте стандартную обработку.

</details>

<details>

<summary>Комбинирование нескольких зон</summary>

Проверьте, находится ли устройство внутри любой из нескольких ограниченных зон:

```jexl
inGeofence(35229 /* Delivery zone #4 */) == true || inGeofence(85269 /* Construction site 1 */) == true
```

Каждая функция сравнивается с `== true`, поэтому пакет, для которого одна из них не может принять решение, не останавливает всё условие. Без сравнения первая функция, которая возвращает пустое значение, останавливает условие, а остальные зоны никогда не проверяются. См. [Когда функция зоны не дает ответа](#when-a-geofence-function-gives-no-answer).

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

</details>

<details>

<summary>Зона в сочетании с параметром устройства</summary>

Выявите превышение скорости в пределах определенной городской зоны:

```jexl
inGeofence(84762 /* destination1 */) == true && value('speed', 0, 'valid') > 50
```

* **Ветка THEN**: Зарегистрируйте контроль скорости, привязанный к этой зоне, или отправьте целевое оповещение.
* **Ветка ELSE**: Продолжайте стандартную обработку для данных, соответствующих требованиям, или данных вне зоны.

</details>

<details>

<summary>Сравнение с предыдущей позицией</summary>

Определите переход из-за пределов зоны внутрь, сравнив текущую позицию с предыдущей:

```jexl
inGeofence(35229 /* Delivery zone #4 */) == true && inGeofence(35229 /* Delivery zone #4 */, 1, 'valid') == false
```

Это выражение возвращает `true` только на первом пакете после того, как устройство входит в зону. `enterGeofence()` делает то же самое за один вызов, поэтому используйте эту форму только тогда, когда вам нужен другой индекс, чем у предыдущего пакета.

Второй вызов сравнивается с `== false`, поэтому выражение срабатывает только тогда, когда предыдущая позиция известна и находилась вне зоны. Устройство без предыдущей допустимой позиции не подходит. Не записывайте второй член как `!inGeofence(...)`, что не дает результата вообще, когда отсутствует предыдущая позиция для проверки.

</details>

## Запись текущей зоны

`geofenceName()` показывает, в какой зоне находится устройство, вместо проверки одной заранее выбранной зоны. Оно возвращает имя в виде текста, а вы сохраняете этот текст в отдельном атрибуте.

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

| Пакет данных | `current_zone`     |
| ------------ | ------------------ |
| 08:14        | `Главный гараж`    |
| 09:02        | (пусто)            |
| 09:47        | `Объект клиента 3` |

Вы создаете его как вычисляемый атрибут в **Вычисление атрибута** узел. Далее он ведёт себя как любой другой вычисляемый атрибут: он отображается в [Анализ данных](/docs/user/ru/guide/account/iot-logic/data-stream-analyzer.md), его можно отображать на платформе как пользовательский датчик, и его можно передавать во внешнюю систему.

### Перед началом работы

**Эту опцию необходимо включить в вашем аккаунте.** `geofenceName()` продается отдельно и по умолчанию отключена для всех. Свяжитесь со своим поставщиком услуг и попросите его включить функцию названия зоны для вашей учетной записи. При этом полезно указать внутреннее название функции, `iot_logic_зона_поиск`.

Пока функция не включена, поток, использующий эту функцию, нельзя сохранить. Узел помечен этой ошибкой:

```
Функция geofenceName() в узле «Определить текущую зону» (#2) недоступна для вашей учетной записи
```

Удалите функцию из узла, чтобы сохранить поток, или дождитесь, пока ваш поставщик услуг включит эту опцию.

**Для поиска вам также нужны зоны.**

* В вашей учетной записи есть как минимум одна зона. См. [Зоны](/docs/user/ru/guide/tracking/map-tools/geofences.md).
* Чтобы искать только часть ваших зон, присвойте им теги. См. [Используйте теги](/docs/user/ru/guide/tracking/map-tools/geofences.md#use-tags) и [Теги](/docs/user/ru/guide/account/tags.md).

### Добавьте атрибут

Создайте вычисляемый атрибут обычным способом, как описано в [Управление атрибутами](/docs/user/ru/guide/account/iot-logic/nodes/initiate-attribute-node/managing-attributes.md#creating-attributes), а затем введите одну из приведенных ниже формул в **Формула** поле.

Введите имя функции самостоятельно. Автодополнение атрибута не предлагает `geofenceName`, а селектор зоны доступен только в узле. **IF/THEN Логика** узле.

### Формулы

Первые две формы охватывают большинство случаев. Третья читает предыдущее положение вместо текущего.

| Формула                        | Что возвращает                                                              |
| ------------------------------ | --------------------------------------------------------------------------- |
| `geofenceName()`               | Имя любой зоны, в которой устройство находится в данный момент              |
| `geofenceName('depots')`       | Имя зоны с тегом `депо` в которой в настоящее время находится устройство    |
| `geofenceName('', 1, 'valid')` | Имя любой зоны, в которой устройство находилось на один пакет данных раньше |

Все три параметра необязательны:

* **Тег**, во-первых, ограничивает поиск зонами, которым вы присвоили это имя. Регистр не имеет значения, а пустой тег означает все зоны. Использование тегов важно, когда у вас много зон и только некоторые из них имеют значение для этого атрибута, например депо, но не объекты клиентов.
* **Номер пакета**, во-вторых, задаёт, насколько далеко назад искать: `0` это обрабатываемый пакет, `1` предыдущий и так далее. Не указывайте его для текущей позиции.
* **Фильтр по позиции**, третьим, — `'действительный'` чтобы пропускать пакеты, которые не содержали позицию, или `'все'` чтобы учитывать их. Если его не указывать, пакеты без позиции будут учтены.

Для точных ограничений каждого параметра см. [Функция названия зоны](/docs/iot-logic-api/technical-details/geofence-name.md) в документации API IoT Logic.

### Что вы получите в ответ

Атрибут хранит название зоны в виде текста или пустое значение, когда указать нечего. Оно пустое, когда:

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

Пустое значение выглядит одинаково во всех трех случаях. В формуле это пустое значение записывается как `null`, именно так в примере маршрутизации ниже выполняется его проверка.

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

```jexl
geofenceName() ?: 'Вне всех зон'
```

Когда точка находится внутри двух перекрывающихся зон, функция возвращает одно из двух названий. Navixy не ранжирует перекрывающиеся зоны, и одно и то же название возвращается до тех пор, пока устройство остается в области перекрытия.

### Примеры формул

<details>

<summary>Текущее название зоны как атрибут</summary>

В **Вычисление атрибута** узле создайте атрибут с именем `current_zone` с такой формулой:

```jexl
geofenceName()
```

Каждый пакет данных, записанный внутри зоны, получает название этой зоны. Пакеты, записанные вне всех зон, получают пустое значение.

</details>

<details>

<summary>Только те зоны, которые вы пометили</summary>

Пометьте зоны гаражей тегом `депо`, затем создайте атрибут с такой формулой:

```jexl
geofenceName('depots') ?: 'В пути'
```

Устройство внутри гаража получает название этого гаража. Устройство в любом другом месте получает `В пути`, в том числе устройство внутри зоны, у которой нет `депо` тега.

</details>

<details>

<summary>Маршрутизация по области в узле IF/THEN Логика</summary>

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

```jexl
geofenceName('restricted') != null
```

* **Ветка THEN**: Данные, записанные внутри зоны с ограничением. Подключите его к **Вебхук** узлу, чтобы оповестить диспетчера.
* **Ветка ELSE**: Все остальные данные.

Сравните результат с `==` или `!=` только. Операторы `<`, `>`, `<=`, и `>=` не дают пригодного результата, когда значение пустое.

</details>

<details>

<summary>Обнаружение смены зоны</summary>

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

```jexl
geofenceName() != geofenceName('', 1, 'valid')
```

Пустой первый параметр означает все зоны, а `'действительный'` позволяет сравнению пропускать пакеты, в которых не было координат. Без `'действительный'`, пакет без координат интерпретируется как пустое название зоны, и условие сообщает о несуществующей смене.

</details>

## Часто задаваемые вопросы

#### Где найти ID зоны?

Селектор зон отображает в списке название каждой зоны и ее числовой ID. Вы также можете найти ID в интерфейсе зон Navixy. Когда вы выбираете зону в селекторе, ID автоматически вставляется в выражение.

#### Могу ли я сохранить проверку зоны в атрибуте?

Да. Все четыре функции работают как в формуле атрибута, так и в условии маршрутизации. `geofenceName()` Это естественный выбор, потому что он дает вам читаемый текст. Остальные три возвращают значение «да» или «нет» либо пустое значение, когда местоположение неизвестно. Значение «да» или «нет» обычно полезнее для маршрутизации, чем для хранения.

Выбор зоны доступен только в **IF/THEN Логика** узле, поэтому в формуле атрибута вы указываете функцию и идентификатор зоны сами.

#### Почему я не могу сохранить поток, который использует geofenceName?

`geofenceName()` Это платная опция, и по умолчанию она отключена. Обратитесь к поставщику услуг, чтобы её включили для вашей учётной записи. См. [Перед началом работы](#before-you-start).

#### Что произойдёт, если связанная зона будет удалена?

Если зона, на которую ссылается выражение, удалена из вашей учётной записи Navixy, функция больше не сможет вернуть значение и вернёт пустое значение. В **IF/THEN Логика** узле, который использует функцию сам по себе, данные проходят по соединению ELSE. Узел сохраняет свой атрибут как пустое значение, а не как `false`. В условии, которое сочетает функцию с другими терминами, пустое значение может остановить всё условие. В **Вычисление атрибута** узле у атрибута нет значения для этого пакета. См. [Отсутствующие значения в выражениях](/docs/user/ru/guide/account/iot-logic/nodes/missing-values-in-expressions.md).

Поток продолжает выполняться, но вы больше не можете сохранить его, пока не исправите выражение. При повторном сохранении возникает ошибка: `Узел «<node title>» (#<node id>) содержит несуществующие или недоступные геозоны`. Обновите или удалите выражение, чтобы восстановить как маршрутизацию, так и возможность сохранения.

#### Оценивает ли inGeofence текущее GPS-положение устройства?

Да. `inGeofence()` проверяет координаты, указанные в текущем пакете данных, относительно границ Зоны. Каждый пакет оценивается независимо, поэтому результат отражает положение устройства в момент получения этого пакета. Пакет, который не содержит координат, получает пустое значение вместо `true` или `false`.

#### В чем разница между inGeofence и enterGeofence?

`inGeofence()` возвращает `true` для каждого пакета, который сообщает о местоположении внутри зоны. `enterGeofence()` возвращает `true` только для пакета, который фиксирует момент, когда устройство пересекло зону. Используйте `inGeofence` когда нужно применить логику ко всем данным внутри зоны. Используйте `enterGeofence` когда нужно реагировать именно на событие пересечения границы.

#### Почему атрибут ЗонаName всегда пуст?

Проверьте эти причины по порядку:

1. Эта опция не включена для вашей учётной записи. Ранее сохранённый поток продолжает работать, и функция возвращает пустое значение для каждого пакета. См. [Перед началом работы](#before-you-start).
2. Переданный вами тег не назначен ни одной зоне. Имена тегов должны совпадать с тегом, который существует в вашей учётной записи.
3. Устройство действительно находится вне каждой зоны, которую вы искали.
4. У вас очень большое количество зон, а формула не передаёт тег. Передайте тег, чтобы искать меньший набор. Точное пороговое значение указано в [Функция названия зоны](/docs/iot-logic-api/technical-details/geofence-name.md).


---

# 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/geofence-functions.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.
