UniSet  2.6.0
Хранение информации о состоянии с уведомлениями об изменении (IONotifyController)
Класс IONotifyController расширяет набор задач класса IOController.
Для ознакомления с базовыми функциями см. \ref page_IOController

Задачи решаемые IONotifyController-ом (\b IONC):
- \ref sec_NC_AskSensors
- \ref sec_NC_Consumers
- \ref sec_NC_Thresholds
- \ref sec_NC_Depends

@section sec_NC_AskSensors Механизм заказа датчиков
Главной задачей класса IONotifyController является уведомление

объектов (заказчиков) об изменении состояния датчика (входа или выхода).

Механизм функционирует по следующей логике: "заказчики" уведомляют IONC об изменении какого именно датчика они хотят получать уведомление, после чего, если данный датчик меняет своё состояние, заказчику посылается сообщение uniset::SensorMessage содержащее информацию о текущем(новом) состоянии датчика, времени изменения и т.п. В случае необходимости можно отказатся от уведомления. Для заказа датчиков предусмотрен ряд функций. На данный момент рекомендуется пользоватся функцией IONotifyController::askSensor.

@section sec_NC_Consumers  Заказчики

В качестве "заказчиков" могут выступать любые UniSet-объекты (UniSetObject), обладающие "обратным адресом" (идентификатором), по которому присылается уведомление об изменении состояния. Свой обратный адрес, объекты указывают непосредственно при заказе (см. IONotifyController::askSensor).

Помимо "динамического" заказа во время работы процессов, существует возможность задавать список заказчиков на этапе конфигурирования системы ("статический" способ). Для этого в конфигурационном файле, в секции <sensors> у каждого датчика предусмотрена специальная секция <consumers>.

<sensors>
...
<item name="Sensors1" textname="sensor N1" iotype="AI" ...>
<consumers>
<consumer name="TestProc1" type="objects"/>
<consumer name="TestProc2" type="managers" node="RemoteNode"/>
...
</consumers>
</item>
...
</sensors>

"Статический" способ заказа гарантирует, что при перезапуске IONC список заказчиков будет восстановлен по конфигурационному файлу.

@section sec_NC_Thresholds Пороговые датчики

@section sec_NC_Depends Механизм зависимостей между датчиками
Механизм зависимостей позволяет задать зависимость одного датчика, от другого.

Например пока "разрешающий" датчик не равен "1", у зависимого держится значение "0". Зависимость настраивается в конфигурационном файле, непосредственно у "зависимого датчика".
Доступные настройки:

...
<sensors ..>
...
<item id="11" iotype="AI" name="AI11_AS" textname="AI 11" depend="Input4_S" depend_off_value="-50"/>
...
</sensors>

В данном примере можно увидеть, что датчик AI11_AS зависит от датчика Input4_S и пока Input4_S=0, в AI11_AS будет записано значение -50. Как только Input4_S=1 в AI11_AS - появиться его истинное значение.

Заметки
Следует иметь ввиду, что для ЗАВИСИМОГО датчика функция setValue(..) действует как обычно и даже если он "заблокирован", значение в него можно сохранять. Оно "появиться" как только сниметься блокировка.
@section sec_NC_Optimization Оптимизация работы со списком "заказчиков"
Для оптимизации поиска списка заказчиков для конкретного датчика используется поле userdata (void*) у USensorInfo!
Это опасный и "некрасивый" хак, но который позволяет избавиться от одного лишнего поиска по unordered_map<SensorID,ConsumerList>.
Суть в том что к датчику через usedata мы привязываем указатель на список заказчиков. Сделано через userdata,
т.к. сам map "хранится" в IOController и IONotifyController не может поменять тип (в текущей реализации по крайней мере).
В userdata задействованы два места (см. UserDataID) для списка заказчиков и для списка порогов.