Перед тем, как перейдем к описанию:
Мы понимаем, что нашим клиентам хотелось бы сконцентрироваться на разработке проектов, а не разбираться в ООП и особенностях реализации компонентов. Мы зафиксировали у себя необходимость получать текст последней возникшей тревоги. В будущем постараемся упростить это.
Собственно описание:
Получение информации от AlarmManager'a основано на использовании поведения
Издатель-Подписчик.
Где издатель (AlarmManager) автоматически информирует подписчика о своих событиях (например, сообщает о активации-деактивации тревоги).
Для того, чтобы это стало возможным понадобится создать функциональный блок - обработчик активных аварий
Код:
FUNCTION_BLOCK LastAlarmMessageClient IMPLEMENTS
AlarmManager.IAlarmManagerClient
У этого ФБ должны быть следующие методы:
Код:
(*
Метод вызывается AlarmManager'ом каждый раз после того, как обновился
список активных тревог.
*)
METHOD ActiveAlarmsChanged
VAR
_iActiveAlarmsCount : INT;
_paitfActiveAlarms : POINTER TO ARRAY[0..0] OF AlarmManager.IAlarm
:= 0;
END_VAR
Код:
(*
Метод вызывается AlarmManager'ом каждый раз после того, как в архив тревог
добавлена новая тревога, или изменена уже присутствующая в архиве тревога
*)
METHOD AlarmStorageModified
VAR
udiResult : UDINT;
END_VAR
Код:
(*
Возвращает критерий по которому AlarmManager определит о каких тревогах
необходимо уведомлять этого подписчика
*)
METHOD GetFilterCriteria : AlarmManager_Interfaces.IAlarmFilterCriteria
AlarmManager'у необходимо дать знать о нашем подписчике. Сделать это можно разными способами.
Я использую метод FB_Init.
Этот метод вызывается во время "Создания" экземпляра ФБ. (В общем случае - в момент загрузки программы в ПЛК или после перезагрузки ПЛК).
Метод должен иметь следующий интерфейс
Код:
(*
Конструктор. Вызывается при создании экземпляра ФБ
*)
METHOD PUBLIC FB_Init : BOOL
VAR_INPUT
bInitRetains : BOOL; // TRUE: the Retain-variables are initialized (reset warm / reset cold)
bInCopyCode : BOOL; // TRUE the instance will be copied to the copy-code afterward (online change)
END_VAR
Наполнение метода следующее:
Код:
// Подписываюсь на события AlarmManager'а
AlarmManager.g_AlarmHandler.RegisterClient (THIS^, 0, 0);
где
THIS^ - сообщает AlarmManager'у, что подписчиком необходимо добавить этот экземпляр ФБ,
0, 0 - в данном примере не используется (описывают где и сколько AlarmManager может хранить тревог при чтении архива тревог).
Кроме этого подписчик должен сообщить AlarmManager'у какие именно тревоги ему интересны.
Это реализовано в ФБ
ShowAllAlarms. Добавил максимум комментариев. Дублировать сюда не буду.
Итак, с созданием подписчика закончили.
Приступим к обработке тревог. Нас интересует метод
ActiveAlarmsChanged, который AlarmManager будет вызывать каждый раз при активации-деактивации тревоги.
Получить перечень активных тревог можно выполнив следующий код:
Код:
// Получаем список активных тревог
AlarmManager.g_AlarmHandler.GetActiveAlarms(
itfAlarmManagerClient := THIS^,
iCountActiveAlarms => _iActiveAlarmsCount,
parritfActiveAlarms => _paitfActiveAlarms);
В переменную _iActiveAlarmsCount будет записано количество активных тревог, а
в _paitfActiveAlarms - указатель на массив активных тревог.
В этом массиве тревоги отсортированы по возрастанию ID, поэтому нам нужно будет найти тревогу, которая активировалась последней.
В примере это выполняет метод
prv_getLastAlarmMessage, я добавил в него комментарии, поэтому не буду дублировать сюда.