Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cs/ds/alarm-handler
  • francesco.tripaldi/alarm-handler
2 results
Show changes
Commits on Source (97)
Showing with 788 additions and 13 deletions
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
*.out *.out
*.app *.app
bin/ bin/
build/
.nse_depinfo .nse_depinfo
......
image:
name: harbor.skao.int/production/ska-tango-images-tango-dsconfig:1.5.5
stages:
- build
- test
build_job:
stage: build
tags:
- docker
before_script:
- sudo apt update && sudo apt -y --no-install-recommends install build-essential cmake pkg-config libboost-thread-dev
script:
- mkdir build && cd build
- cmake -DBUILD_TESTS=ON ..
- make
artifacts:
paths:
- build/alarm-handler-srv
- build/bin/testdevice-srv
expire_in: 1 week
test_load_job:
stage: test
tags:
- docker
before_script:
- sudo apt update && sudo apt -y --no-install-recommends install libboost-thread-dev
script:
- sleep 10
- /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 &
- sleep 10
- exit_code=2
- json2tango -w -a -u ./test/ah_config.json || exit_code=$?
- if [ ${exit_code} -ne 2 ]; then echo "Tango DB configuration failed!" ; else echo "Tango DB configuration succedeed!"; fi
- ./build/alarm-handler-srv 01 &
- ./build/bin/testdevice-srv 01 &
- sleep 5
- python ./test/load-alarm-conf.py --device=alarm/handler/01 --load="tag=test0;formula=(alarm/test/01/condition == 1);on_delay=0;off_delay=0;priority=high;shlvd_time=0;group=gr_test;message=Test alarm;url=;on_command=;off_command=;enabled=1"
- sleep 1
- python ./test/check-alarm-conf.py --device=alarm/handler/01 --alarm="tag=test0;formula=(alarm/test/01/condition == 1);on_delay=0;off_delay=0;priority=high;shlvd_time=0;group=gr_test;message=Test alarm;url=;on_command=;off_command=;enabled=1"
needs: ["build_job"]
services:
- name: harbor.skao.int/production/ska-tango-images-tango-db:10.4.16
alias: tangodb
image:
name: harbor.skao.int/production/ska-tango-images-tango-dsconfig:1.5.5
# The following variables are automatically passed down to the tangodb container
# as well as the tangodatabaseds container and available within each.
variables:
MYSQL_ROOT_PASSWORD: "secret"
MYSQL_DATABASE: "tango"
MYSQL_USER: "tango"
MYSQL_PASSWORD: "tango"
MYSQL_HOST: "tangodb"
TANGO_HOST: "localhost:10000"
stages:
- build
- conf
- test
services:
- name: harbor.skao.int/production/ska-tango-images-tango-db
alias: tangodb
# - name: harbor.skao.int/production/ska-tango-images-tango-cpp
# alias: tangodatabaseds
# entrypoint: ["/usr/local/bin/DataBaseds"]
# command: ["2","-ORBendPoint giop:tcp::10000"]
build_job:
stage: build
before_script:
#TODO: remove procps use for ps
- sudo apt update && sudo apt -y --no-install-recommends install build-essential cmake pkg-config libboost-thread-dev procps
script:
#- make
- mkdir build && cd build
- cmake ..
- make
artifacts:
paths:
- build/alarm-handler-srv
expire_in: 1 week
# # depending on your build setup it's most likely a good idea to cache outputs to reduce the build time
# cache:
# paths:
# - build/CMakeFiles/
configure_and_run_job:
stage: conf
script:
- sleep 10
- /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 &
- sleep 10
- exit_code=2
- json2tango -w -a -u ./test/ah_config.json || exit_code=$?
# json2tango returns 2 if values written to DB
- if [ ${exit_code} -ne 2 ]; then echo "Tango DB configuration failed!" ; else echo "Tango DB configuration succedeed!"; fi
- sleep 5
artifacts:
paths:
- build/alarm-handler-srv
expire_in: 1 week
needs: ["build_job"]
#services:
# - name: harbor.skao.int/production/ska-tango-images-tango-db
# alias: tangodb
test_job:
stage: test
before_script:
#TODO: remove procps use for ps
- sudo apt update && sudo apt -y --no-install-recommends install libboost-thread-dev procps
script:
- /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 &
- sleep 10
- ./build/alarm-handler-srv 01 &
- sleep 10
- ps -ef | grep alarm-handler-srv | grep -v grep
- sleep 5
needs: ["configure_and_run_job"]
[submodule ".makefiles"]
path = .makefiles
url = https://github.com/ELETTRA-SincrotroneTrieste/makefiles.git
Subproject commit 3c45cfb725c2c01479525a015a6a9bd671980bf4
# Functions and Pre-build -----------------------------------
# Stop messy in source builds
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES OFF)
if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." )
endif()
# Start Build Config -----------------------------------
cmake_minimum_required(VERSION 3.8)
set(CMAKE_SKIP_RPATH true)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Output name for the final binary
set(AH_NAME "alarm-handler-srv")
# Versioning
set(VERSION_MAJOR "1")
set(VERSION_MINOR "0")
set(VERSION_PATCH "0")
set(VERSION_METADATA "")
set(VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
# Add any include paths from the command line
list(APPEND INCLUDE_PATHS ${CMAKE_INCLUDE_PATH})
list(APPEND INCLUDE_PATHS ${CMAKE_SOURCE_DIR})
list(APPEND LIBRARY_PATHS ${CMAKE_LIBRARY_PATH})
# Start the project
project(alarm_handler VERSION ${VERSION_STRING} LANGUAGES CXX)
# Build options
option(ENABLE_CLANG "Enable clang code and layout analysis" OFF)
option(BUILD_TESTS "Build tests" OFF)
# arch install definitions
include(GNUInstallDirs)
message(STATUS "Searching for libraries...")
# Variable to contain a list of all the libs we depend on
set(AH_LIBRARIES)
# allow pkg-config to search the CMAKE_PREFIX_PATH
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
list(APPEND CMAKE_PREFIX_PATH "/usr")
# Find Dependencies -----------------------------------
# Find tango if it has not already been found. Returns an interface library
# called TangoInterfaceLibrary
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(Tango)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.65.0 COMPONENTS thread)
# Code Analysis -----------------------------------
if(ENABLE_CLANG)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# To find clang, find_program will search your PATH environment variable.
# Ensure if you have a non-standard clang install, that it has been added
# to your path.
find_program(CLANG_TIDY_EXE
NAMES "clang-tidy"
DOC "Path to clang-tidy executable")
if(NOT CLANG_TIDY_EXE)
message(STATUS "clang-tidy not found.")
else(NOT CLANG_TIDY_EXE)
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}")
endif(NOT CLANG_TIDY_EXE)
endif(ENABLE_CLANG)
# Source -----------------------------------
add_subdirectory(src)
# Build Targets -----------------------------------
# Executable --------
add_executable(alarm_handler ${SRC_FILES})
target_link_libraries(alarm_handler
PRIVATE
TangoInterfaceLibrary
${Boost_LIBRARIES}
)
target_include_directories(alarm_handler
PRIVATE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
${INCLUDE_PATHS}
"${PROJECT_BINARY_DIR}"
${Boost_INCLUDE_DIRS})
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
set_target_properties(alarm_handler
PROPERTIES
OUTPUT_NAME ${AH_NAME}
LINK_FLAGS "-Wl,--no-undefined"
CXX_STANDARD 17)
else()
set_target_properties(alarm_handler
PROPERTIES
OUTPUT_NAME ${AH_NAME}
LINK_FLAGS ""
CXX_STANDARD 17)
endif()
if(DO_CLANG_TIDY)
set_target_properties(alarm_handler
PROPERTIES
CXX_CLANG_TIDY ${DO_CLANG_TIDY})
endif(DO_CLANG_TIDY)
target_compile_options(alarm_handler
PRIVATE "$<$<CONFIG:DEBUG>:-g>")
# Install Config -----------------------------------
install(
TARGETS alarm_handler
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
message(STATUS "Configured alarm-handler project")
# Tests -----------------------------------
if(BUILD_TESTS)
add_subdirectory(test)
endif(BUILD_TESTS)
NAME_SRV = alarmhandler-srv NAME_SRV = alarm-handler-srv
CXXFLAGS += `mysql_config --include` CXXFLAGS +=
LDFLAGS += `mysql_config --libs_r` -lboost_thread LDFLAGS += -lboost_thread
include ./.makefiles/Make-9.2.2.in include ../makefiles/Make-9.3.3.in
# alarm # Alarm-handler
Elettra AlarmHandler Elettra alarm-handler Tango device
## building ## Documentation
git clone --recursive http://github.com/ELETTRA-SincrotroneTrieste/alarmhandler.git
cd alarmhandler [Alarm-handler](docs/AlarmHandler.md)
## Building and Installation
In its simplest form, clone the repository and assuming a standard install for all dependencies:
```
mkdir build
cd build
cmake ../
make
make install
```
### pkg-config Settings
The build system uses pkg-config to find some dependencies, for example Tango. If Tango is not installed to a standard location, set PKG_CONFIG_PATH, i.e.
```bash
export PKG_CONFIG_PATH=/non/standard/tango/install/location
...
cmake ../
...
```
The pkg-config path can also be set with the cmake argument CMAKE_PREFIX_PATH. This can be set on the command line at configuration time, i.e.:
```bash
...
cmake -DCMAKE_PREFIX_PATH=/non/standard/tango/install/location ../
...
```
### Project Flags
| Flag | Setting | Default | Description |
|------|-----|-----|-----|
| BUILD_TESTS | ON/OFF | OFF | Build test devices under test directory |
### Standard CMake Flags
The build system is CMake therefore standard CMake flags can be used to influence the build and installation process. The following is a list of common useful CMake flags and their use:
| Flag | Use |
|------|-----|
| CMAKE_INSTALL_PREFIX | Standard CMake flag to modify the install prefix. |
| CMAKE_INCLUDE_PATH | Standard CMake flag to add include paths to the search path. |
| CMAKE_LIBRARY_PATH | Standard CMake flag to add paths to the library search path |
## Legacy Building
Using Elettra makefiles, clone both alarm-handler and makefile repositories, then call make:
```bash
git clone http://gitlab.elettra.eu/cd/ds/makefiles.git
git clone http://gitlab.elettra.eu/cs/ds/alarm-handler.git
cd alarm-handler
make make
```
include(CMakeParseArguments)
function(find_libraries)
# Parse the parameters
set(MULTIVALUEARGS LIBRARIES SEARCH_PATHS)
cmake_parse_arguments(FIND_LIBRARIES "" "" "${MULTIVALUEARGS}" ${ARGN})
# Clear the found libraries
unset(FOUND_LIBRARIES PARENT_SCOPE)
foreach(LIB ${FIND_LIBRARIES_LIBRARIES})
# try the user provided paths first
find_library(FOUND_LIB_${LIB} ${LIB} PATHS ${FIND_LIBRARIES_SEARCH_PATHS} NO_DEFAULT_PATH)
# if we could not find it, drop to the system paths
if(NOT FOUND_LIB_${LIB})
find_library(FOUND_LIB_${LIB} ${LIB})
endif(NOT FOUND_LIB_${LIB})
if(FOUND_LIB_${LIB})
message(STATUS "Found " ${LIB} " at: " ${FOUND_LIB_${LIB}})
list(APPEND FOUND_LIBRARIES ${FOUND_LIB_${LIB}})
else()
message(FATAL "Could not find " ${LIB})
endif(FOUND_LIB_${LIB})
endforeach(LIB ${LIBRARIES})
set(FOUND_LIBRARIES ${FOUND_LIBRARIES} PARENT_SCOPE)
endfunction(find_libraries)
\ No newline at end of file
if(NOT TARGET TangoInterfaceLibrary)
# Ensure pkg-config is installed
find_package(PkgConfig REQUIRED)
# Now search for the tango.pc file, this is a required dependency
message(STATUS "Search for TANGO package config...")
pkg_search_module(TANGO REQUIRED tango>=9.2.5)
message(STATUS "Found tango version ${TANGO_VERSION} at ${TANGO_PREFIX}")
include(FindLibraries)
find_libraries(LIBRARIES ${TANGO_LIBRARIES} SEARCH_PATHS ${TANGO_LIBRARY_DIRS})
# Create an interface library to represent the tango linkage
add_library(TangoInterfaceLibrary INTERFACE)
set_target_properties(TangoInterfaceLibrary
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${TANGO_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${FOUND_LIBRARIES}"
INTERFACE_COMPILE_OPTIONS "${TANGO_CFLAGS}")
message(STATUS "Configured Tango Interface for TANGO version ${TANGO_VERSION}")
endif(NOT TARGET TangoInterfaceLibrary)
\ No newline at end of file
# The Alarm Ecosystem
There are several projects related to alarms, which can work together with AlarmHandlers.
## AlarmNotify
[alarm-notify](https://gitlab.elettra.eu/cs/ds/alarm-notify) connect to a list of alarm-handler devices and subscribes for the change event of their alarm attributes. It checks whether there are Recipients configured in individual alarms, or interested in alarms belonging to a group, or all alarms, then builds a list of recipients for each alarm state of each alarm.
When an event is received, if there are recipients configured for the new alarm state, a command is triggered on a device for notification.
A string parameter with a semicolon-separated list of “key=value” fields is passed to the notification command, with the following keys:
```
name=<_tag_>;handler=<AlarmHandler device>;values=<JSON attribute values>url=<_url_>;msg=<_msg_>;formula=<_formula_>;groups=<_groups_>;shlvd_time=<_shlvd_time_>;state=<Alarm state DevEnum label>;ack=<true|false>;time=<timestamp>;
```
See an example of configuration properties:
![screenshot](images/alarm_notify_properties.png)
## AlarmManager
[alarm-manager](https://gitlab.elettra.eu/cs/ds/alarm-manager) is a Tango device server that supports the configuration of AlarmHandlers. AlarmHandlers are designed to be modular, so that different AlarmManagers can be configured to handle different groups/subsets of AlarmHandlers.
AlarmManager can display the selected alarm configuration as attributes (_tag_, _formula_, _message_, _priority_, _group_, _shlvd_time_, _on_delay_, _off_delay_, _on_command_, _off_command_, _receivers_) or can Load/Modify alarms with the configuration provided in the attributes (_tag_, _formula_, _message_, ... same list as above)
## AlarmMail
[alarm-mail](https://gitlab.elettra.eu/cs/ds/alarm-mail) is a Tango device server which exports commands able to send emails. Its commands can be configured in _on_command_ and _off_command_ properties (deprecated) or called by AlarmNotify.
## AlarmHandlerGUI
[alarm-handler-gui](https://gitlab.elettra.eu/cs/gui/alarm-ng) is the default AlarmHandler GUI at [Elettra](www.elettra.eu). It is designed to display different sets of AlarmHandlers. See:
![screenshot](images/alarm_ng.png)
The different lists of AlarmHandlers to use are taken from free properties. Same properties that can be used to configure AlarmManagers. See:
![screenshot](images/free_properties.png)
AlarmHandlerGUI is also able to display and search in alarm history stored by HDB++ (MySQL schema only). See:
![screenshot](images/alarm_ng_history.png)
## AlarmManagerGUI
[alarm-manager-gui](https://gitlab.elettra.eu/cs/gui/alarm-manager) displays in a tree the list of alarms read from the AlarmManager's _alarmList_ attribute. When an alarm is selected in the tree, AlarmManager's _tag_ and _handler_ are written accordingly and all the other attributes contain the updated configuration, see:
![screenshot](images/alarm_manager.png)
This can then be modified or loaded as a new alarm if the _tag_ attribute has changed.
## HDB++
[EventSubscriber](https://gitlab.com/tango-controls/hdbpp/hdbpp-es) can be used to store alarm history: alarm are exported by the AlarmHandler interface as DevEnum attributes whose change and archive events are pushed in the code at any variation. The configuration of HDB++ is independent of the AlarmHandlers, but also AlarmManagerGUI can also do this.
## PANIC
[PANIC](https://gitlab.com/tango-controls/panic) is the Alarm System developed at [Alba](https://www.cells.es). Preliminary work has been done to support AlarmHandler as an alarm formula evaluation device for PANIC. Specifically, the _alarmSummary_ attribute, GetAlarmInfo command and alarm Devenum attributes are compatible between the two systems. PANIC should also be able of handle the configuation of AlarmHandlers in attribute properties, but the work has not yet been finalized.
# Alarm Handler
AlarmHandler is a Tango device server which manage alarms in compliance with IEC 62682 standard. It evaluates the formulas that define the alarm condition and creates a dynamic attribute for each alarm rule to export the state of the alarm. Having the alarm state in the attributes enables asynchronous notification of clients interested in alarm changes, with the granularity of one alarm. In fact, each attribute representing an alarm can push events when its state changes. Clients can subscribe to events of the alarm attributes they are interested in, or the events of all attributes, and be notified asynchronously. Clients can be graphical user interfaces, notifiers, other AlarmHandlers or any TANGO device in general.
The configuration of each alarm is saved in the Tango Database as attribute properties.
## Configuration
Configuration uses both device/class and attribute properties.
### Device/Class properties
Device properties are for configurations that apply to the entire device. The same properties can also be defined as Class properties, in which case they apply to all devices of the AlarmHandler Class in which the Device Property of the same name is not defined.
| Name | Description | Type | Default Value |
|------|-----|:-----:|:-----:|
| GroupNames | Labels for Group mask, first is for mask 0x00 so ‘none’ is the default label associated to it. Second label is associated to the mask 0x1, third to the mask 0x2, ... <br>Only labels defined here can be used as group names in the alarm configuration. | String[] | none |
| SubscribeRetryPeriod | Change event subscription period in seconds. Every time this period expires AlarmHandler tries to re-subscribe all faulty attributes | DevLong | 30 |
| _StatisticsTimeWindow_ | **Not implemented** | DevLong[] | 60 |
| ErrorDelay | Delay in seconds before going to ERROR state after receiving an exception. | DevULong | 30 |
| SetAlarmQuality | Set the alarm attribute quality as evaluated using the attribute quality in the formula | DevBoolean | false |
### Attribute properties
The following attribute properties are used to store the configuration of alarms. They are present for each attribute that has the same name as the alarm name. Some of these properties are mandatory, others optional.
| Name | Description | Mandatory | Default Value |
|------|-----|:-----:|:-----:|
| tag | Alarm name (same as the attribute name) | Yes | |
| formula | Alarm formula | Yes | |
| on_delay | Delay in seconds before the alarm becomes active after the formula result has changed from false to true | No | 0 |
| off_delay | Delay in seconds before the alarm becomes inactive after the formula result has changed from true to false | No | 0 |
| priority | Severity of the alarm. 'highest', 'high', 'medium', 'low', 'lowest','fault', 'warning' and 'log' are allowed | Yes | |
| silent_time | Time in minutes when the alarm will be silenced or shelved with the _Silence_ and _Shelve_ commands. If -1, the alarm cannot be silenced or shelved. | No | -1 |
| group | One or more groups to which this alarm belongs. The possible groups are defined in the device property GroupNames. Multiple groups are specified by concatenating with the \| character | Yes | |
| message | Additional message carried with the alarm | Yes | |
| on_command | No | Command executed when the alarm becomes active. Command argin has to be DEV_VOID or DEV_STRING. In the second case the string _“name=...;groups=...;msg=…;values=…;formula=...”_ is passed as the argument | "" |
| off_command | No | Command executed when the alarm becomes inactive. Command argin has to be DEV_VOID or DEV_STRING. In the second case the string _“name=...;groups=...;msg=…;values=…;formula=...”_ is passed as the argument | "" |
| enabled | If true alarm is enabled, otherwise it is set to the OOSRV - out of service alarm state | No | 1 |
| receivers | List of alarm states colon list of email recipients. Used only by [alarm-notify](https://gitlab.elettra.eu/cs/ds/alarm-notify) | No | "" |
### Formula syntax
See [Formula.md](./Formula.md).
## Interface
### Attributes
#### Dynamic Attributes
| Name | Attr. type | R/W type | Data type | Description |
|------|:-----:|:-----:|:-----:|-----|
| AlarmState | Scalar | READ |DEV_ENUM <br>Labels: NORM, UNACK, ACKED, RTNUN, SHLVD, DSUPR, OOSRV, ERROR | Dynamically created with the tag name as the attribute name for each alarm |
#### Static Attributes
| Name | Attr. type | R/W type | Data type | Description |
|------|:-----:|:-----:|:-----:|-----|
| alarmAudible | Scalar | READ | DEV_BOOLEAN | True if there is at least one alarm that needs an audible indication on the GUI |
| StatisticsResetTime | Scalar | READ | DEV_DOUBLE | Time elapsed in seconds since last ResetStatistics command |
| alarm | Spectrum | READ | DEV_STRING | List of active (UNACK or ACKED) alarms and and their status. Format described below |
| alarmDisabled | Spectrum | READ | DEV_STRING | List of disabled (OOSRV or SHLVD) alarms and and their status. Format described below |
| alarmNormal | Spectrum | READ | DEV_STRING | List of alarm names in NORM state |
| alarmUnacknowledged | Spectrum | READ | DEV_STRING | List of alarm names in UNACK state |
| alarmAcknowledged | Spectrum | READ | DEV_STRING | List of alarm names in ACKED state |
| alarmUnacknowledgedNormal | Spectrum | READ | DEV_STRING | List of alarm names in RTNUN state |
| alarmShelved | Spectrum | READ | DEV_STRING | List of alarm names in SHLVD state |
| alarmOutOfService | Spectrum | READ | DEV_STRING | List of alarm names in OOSRV state |
| alarmSilenced | Spectrum | READ | DEV_STRING | List of alarm names in silenced state |
| alarmList | Spectrum | READ | DEV_STRING | List of all alarm names |
| alarmFrequency | Spectrum | READ | DEV_DOUBLE | List of alarms frequency, i.e. the number of times alarms have occurred since the last _ResetStatistics_ command |
| alarmSummary | Spectrum | READ | DEV_STRING | List of all alarms and their status. Format described below |
| eventList | Spectrum | READ | DEV_STRING | List of all attributes subscribed (attributes present in formulas) |
| eventSummary | Spectrum | READ | DEV_STRING | List of all attributes subscribed and their status. Format described below |
* _alarm_
```
<timestamp seconds>\t<timestamp us>\t<tag>\t<ALARM|NORMAL|ERROR>\t<ACK|NACK>\t<priority>\t<silenced time>\t<group>\t<message>
Example:
1740990955 124920 pssip_kg09.05_ch1_off ALARM ACK high 0 gr_vac sip300_l04.05 PS not ON
1741280601 438811 pssip_ctf.03_ch3_off NORMAL NACK high 0 gr_vac sip_ctf.07 PS not ON
1741595157 64811 pssip_kg04.01_ch1_off ERROR ACK high 0 gr_vac Tango error for kg04/vacuum/pssip_kg04.01/stat1: Not valid status
```
* _alarmDisabled_
```
<timestamp seconds>\t<timestamp us>\t<tag>\t<OOSRV|SHLVD>\t<ACK|NACK>\t<priority>\t<silenced time>\t<group>\t<message>
Example:
1740990965 41097 pssip_kg07.15_ch2_off OOSRV NACK high 0 gr_vac sip75_boc_l02.01 PS not ON
```
* _alarmSummary_
```
tag=<tag>;state=<state>;priority=<priority>;time=<date time us>;formula=<formula>;message=<message>;
Example:
tag=pssip_kg09.05_ch1_off;state=ACKED;priority=high;time=2025-03-03 09:35:55.124920;formula=(kg09/vacuum/pssip_kg09.05/state1 == 0);message=sip300_l04.05 PS not ON
tag=pssip_ctf.03_ch3_off;state=ACKED;priority=high;time=2025-03-06 18:03:21.438811;formula=(ctf/vacuum/pssip_ctf.03/state3!=ON);message=sip_ctf.07 PS not ON
tag=pssip_kg04.01_ch1_off;state=ERROR;priority=high;time=2025-03-10 09:25:57.64811;formula=(kg04/vacuum/pssip_kg04.01/stat1[0] == 0);message=sip02_kg04.01 PS not ON
```
* _eventSummary_
```
event=<attribute fqdn>;time=<date time s>;values=<attribute values>;exception=<attribute exception>;quality=<attribute quality>;
Example:
event=usa/vacuum/pssip_usa.22/stat1;time=2025-03-12 13:50:51;values=[1,1,0,1,1,0,0,0];exception=;quality=ATTR_VALID
event=kg15/vacuum/pssip_kg15.01/stat1;time=2025-03-14 16:49:50;values=[];exception={"Reason":"Event_ERROR","Desc":"Tango error for kg15/vacuum/pssip_kg15.01/stat1: Not valid status","Origin":"kg15/vacuum/pssip_kg15.01/stat1"};quality=ATTR_INVALID;
```
### Commands
| Name | Input argument | Output argument | Description |
|------|:-----:|:-----:|-----|
| Ack | DEVVAR_STRINGARRAY | DEV_VOID | Acknowledge the list of alarms passed as input argument |
| Load | DEV_STRING | DEV_VOID | Load a new alarm as a string of concatenated _“key=value;”_. Possible keys are those documented in the attribute properties. Note: The _SearchAlarm_ command returns strings that have the correct syntax for the _Load_ and _Modify_ input arguments |
| Modify | DEV_STRING | DEV_VOID | Modify an existing alarm. Input argument has the same syntax of the _Load_ command |
| Remove | DEV_STRING | DEV_VOID | Remove completely an alarm. Its configuration is deleted from the attribute properties |
| Enable | DEV_STRING | DEV_VOID | Enable an alarm whose name is passed as the input argument. It has to be in the OOSRV or SHLVD state. Enabled is set to 1 in the attribute properties |
| Disable | DEV_STRING | DEV_VOID | Disable an alarm whose name is passed as the input argument. Its state changes to OOSRV and enabled is set to 0 in the attribute properties. From OOSRV the alarm state can be changed only with the Enable command |
| Shelve | DEVVAR_STRINGARRAY | DEV_VOID | Shelve command disable temporarily the list of alarms passed as input argument. Only alarms which have a silent_time property > 0 can be shelved. Their state is changed to SHLVD for the period specified as silent_time or until the Enable command is called |
| Silence | DEVVAR_STRINGARRAY | DEV_VOID | Silence command disable temporarily the management of the audible condition of the list of alarms passed as input argument. Only alarms which have a silent_time property > 0 can be silenced. Their state continue to change following their normal behavior but they do not participate to the audibleAlarm evaluation for the period specified as silent_time or until the Enable command is called |
| SearchAlarm | DEV_STRING | DEVVAR_STRINGARRAY | Returns the list of configured alarms that match the name of the filter string. If the filter string is empty or *, the command returns the configuration of all alarms. The Alarm configuration is returned as a concatenated _“key=value;”_ string, with the same syntax as the Load command |
| GetAlarmInfo | DEVVAR_STRINGARRAY | DEVVAR_STRINGARRAY | Returns the complete status of the alarm whose name is passed as input argument [0]. The return value is an array of strings _“key=value;”_. Other input arguments may specify keys to be included in the response. Format described below |
| ReLoadAll | DEV_VOID | DEV_VOID | Reaload the configuration of all alarms from attribute properties |
| ResetStatistics | DEV_VOID | DEV_VOID | Reset frequency counters |
| StopAudible | DEV_VOID | DEV_VOID | Reset audibleAlarm attribute |
| StopNew | DEV_VOID | DEV_VOID | Same as StopAudible, kept temporarily for compatibility with legacy alarm GUI |
* _GetAlarmInfo_
Returns the complete status of the alarm whose name is passed as the input argument.
The return value is an array of strings _“key=value;”_. The keys are those described in the attribute properties plus:
* value=one of the alarm state enum labels
* attr_values=concatenation of “attrname=value;” of the last value of attributes evaluated in the formula
* quality=the tango quality
* exception=Reason:.. Desc:.. Origin:..
* shelved=true/false
* ack=ACK/NACK
* audible=true/false
* on_counter=how many times it evaluated consecutively true
* on_counter=how many times it evaluated consecutively false
* freq_counter=how many times is has been evaluated since last ResetStatistics
* silent_time_remaining=how many minutes till when it will come back from shelved or silenced
Example:
```
[0] tag=ks_prealarm_sf6
[1] state=NORM
[2] message="Pre Alarm SF6 on modulator KS"
[3] url=
[4] formula=(ks/interlock/sf6_ks.01/StatSF6[1] == 0)
[5] values={"ks/interlock/sf6_ks.01/statsf6[1]":1}
[6] time=2025-02-09 07:33:19.411087
[7] quality=ATTR_VALID
[8] enabled=1
[9] shelved=0
[10] ack=1
[11] audible=0
[12] counter=2
[13] freq_counter=7
[14] on_delay=0
[15] off_delay=0
[16] priority=high
[17] shlvd_time=-1
[18] shlvd_end=-1
[19] group=gr_ctrl|gr_linac
[20] on_command=
[21] off_command=
[22] receivers=
```
### Alarm states
| Name | Value | Process condition | Alarm status | Acknowledge status | Description |
|------|:-----:|:-----:|-----|-----|-----|
| NORM | 0 | NORMAL | Inactive | Acknowledged | Normal state |
| UNACK | 1 | ABNORMAL | Active | Unacknowledged | Alarm not acnowledged |
| ACKED | 2 | ABNORMAL | Active | Acknowledged | Alarm acknowledged |
| RTNUN | 3 | NORMAL | Inactive | Unacknowledged | Returned to normal not acnowledged |
| SHLVD | 4 | ANY | Any | Not applicable | Shelved: temporarily disabled with the Shelve command |
| DSUPR | 5 | ANY | Any | Not applicable | Suppressed by design: not possible to evaluate to alarm because of formula conditions. Note: it is not possible to enter in this state in this AlarmHandler implementation |
| OOSRV | 6 | ANY | Any | Not applicable | Out of service: manually disabled with the Disable command |
| ERROR | 7 | ANY | Any | Not applicable | Cannot be evaluated due to Tango or formula evaluation errors |
# Alarm Ecosystem
See [Alarm Ecosystem](./AlarmEcosystem.md) for other projects related to AlarmHandlers and how they can be used together.
\ No newline at end of file
# Formula syntax
The formula is an expression with operators, operands and functions. Operands can be variables, constant values, or other expression optionally enclosed by parentheses.
## Operands
### Variables
- Attributes names with or without fqdn (e.g. ```tango://host:port/name/of/dev/attr```, ```name/of/dev/attr```)
- attribute properties ```.quality```, ```.alarm```, ```.normal``` so that
- ```name/of/dev/attr.quality``` returns the Tango quality (the integer value) of the attribute
- ```name/of/dev/attr.alarm``` returns true if the attribute ==UNACK or ==ACK
- ```name/of/dev/attr.normal``` returns true if the attribute ==NORM or ==RTNUN
### Constants
- Real numbers (e.g. ```name/of/dev/attr >= 35```, ```name/of/dev/attr < -23.5```)
- Hexadecimal numbers (e.g. ```name/of/dev/attr != 0xaf```, ```name/of/dev/attr & 0x1A```)
- Strings as any character between an opening and a closing ' (e.g. ```name/of/dev/status == 'The device is in ON state.'```)
- Tango states enum labels (*ON, OFF, CLOSE, OPEN, INSERT, EXTRACT, MOVING, STANDBY, FAULT, INIT, RUNNING, ALARM, DISABLE, UNKNOWN*) (e.g. ```name/of/dev/state == FAULT```)
- Tango quality enum labels (*ATTR_VALID, ATTR_INVALID, ATTR_WARNING, ATTR_ALARM, ATTR_CHANGING*) (e.g. ```name/of/dev/attr.quality == ATTR_ALARM```)
- Alarm state enum labels (*NORM, UNACK, ACKED, RTNUN, SHLVD, DSUPR, OOSRV*) (e.g. ```name/of/dev/alarm_attr != NORM```)
### Expressions
- A combination of operands and operators enclosed by parentheses
## Operators
### Binary Math
- Multiplication ```*```
- Division ```/```
- Addition ```+```
- Subtraction ```-```
### Binary Comparison
- Equal ```==```
- Not equal ```!=```
- Greater than ```>```
- Greater than or equal to ```>=```
- Less than ```<```
- Less than or equal to ```<=```
### Binary Logical
- Logical AND ```&&```
- Logical OR ```||```
### Binary Bitwise
- Left shift ```<<```
- Right shift ```>>```
- Bitwise AND ```&```
- Bitwise OR ```|```
- Bitwise XOR ```^```
### Unary Math
- Minus ```-```
### Unary Logical
- Logical NOT ```!```
### Binary operators order of precedence
```
*, /, +, -, <<, >>, <=, >=, >, <, ==, !=, &, |, ^, &&, ||
```
## Functions
### Unary Functions
- Absolute value of X ```abs(X)```
- Sine of X ```sin(X)```
- Cosine of X ```cos(X)```
### Binary Functions
- Minimum between two values X and Y ```min(X,Y)```
- Maximum between two values X and Y ```max(X,Y)```
- Power: X raised to the power of Y ```pow(X,Y)```
### Ternary Functions
- Conditional operator: if X then Y else Z ```X ? Y : Z```
### Reduce Functions
- Reduce OR: reduce array X applying logical OR to each element ```OR(X)```
- Reduce AND: reduce array X applying logical AND to each element ```OR(X)```
# Attributes types
The following types of attribute are supported:
```
Scalar, Spectrum, Image
```
with data types:
```
DevBoolean, DevUChar, DevShort, DevUShort, DevLong, DevULong, DevLong64, DevULong64, DevFloat, DevDouble, DevString, DevState, DevEnum
```
```DevEncoded``` is not supported.
The read part of every attribute is internally extracted in a vector of double with the ```extract_read``` method of the ```DeviceAttribute``` class. In this ways operations between attribute with different data types and sizes can be performed with the following constraints:
- DevString attributes can only be compared with 'equal' or 'not equal' operators to DevString attributes or string constants
- Binary operators can operate on arrays if both operands have the same size, or one of the two has size equal to one.
# Operation on arrays
## Indexes to access elements
- A single element of a one-dimensional array attribute (Spectrum) can be extracted with a single index between square brackets (e.g. ```name/of/dev/attr[ind]```).
- A single element of a two-dimensional array attribute (Image) can be extracted with two indexes between square brackets (e.g. ```name/of/dev/attr[ind_row][ind_column]```).
- A one-dimensional array can be extracted from a two-dimensional array attribute (Image) with a single index between square brackets (e.g. ```name/of/dev/attr[ind_row]```).
## Lists and ranges of indexes to slice arrays
Indexes can be specified as a comma separated list and/or hyphen-separated range (e.g. ```[i0,i1-i2,...]```).
In this way:
- A slice can be extracted from a one-dimensional array with a list and/or range of indexes between square brackets (e.g. ```name/of/dev/1Dattr[i0,i1-i2,...]```).
- A subset of rows can be extracted from a two-dimensional array with a list and/or range of indexes for the first dimension (e.g. ```name/of/dev/2Dattr[i0,i1-i2,...]```).
- A single column slice can be extracted from a two-dimensional array with a list and/or range of indexes for the first dimension and a single index for the second dimension (e.g. ```name/of/dev/2Dattr[i0,i1-i2,...][i3]```).
- A single row slice can be extracted from a two-dimensional array with a single index for the first dimension and list/range of indexes for the second dimension (e.g. ```name/of/dev/2Dattr[i0][i1-i2,i3,...]```).
- An array slice can be extracted from a two-dimensional array with a list and/or range of indexes for both the first and second dimensions (e.g. ```name/of/dev/2Dattr[i0-i1,...][i2,i3,...]```).
- To specify all elements of one dimension index -1 can be used (e.g. Column 3 of all rows of 2D array ```name/of/dev/2Dattr[-1][3]```).
If any index exceeds actual dimensions of the array, the formula is evaluated to ERROR with an out of bounds exception.
No check is done on the order and uniqueness of indexes, so it is allowed to concatenate duplicated and out of order elements/rows/columns (e.g. ```name/of/dev/2Dattr[0-2,1,0,..]``` evaluates to an array with rows 0,1,2,1,0 of 2Dattr)
## Limitations
- It is not possible to specify array constants (e.g. ```name/of/dev/attr > [val1,val2]```).
- It is not possible to use indexes on expressions (e.g. ```(any_expression)[ind]```).
## Unary operators and functions
Unary operators and functions are applied to every element of the array
## Binary operators and functions
- If both operands have the same size, operators are applied element by element. Result is an array with the same size.
- If one operand has size one, operators apply it to every element of the other operand. Result is an array with the same size.
- Otherwise an exception is raised and the formula is evaluated to the *ERROR* state with the Reason, Descrption and Origin DevFailed fields properly filled.
## Ternary Function
- Conditional operator: if X then Y else Z. X is implicitly reduced with *OR* to have a boolean value, then Y or Z are evaluated depending on the result
# Formula result
Every formula produce a boolean result in the following way:
1. each element of the array is tested as not equal to zero in order to have an array of booleans
2. the array of boolean is reduced with OR (i.e. if at least one element of the array is TRUE, the result is TRUE)
# Errors
If a formula cannot be evaluated, the corresponding alarm is set to the *ERROR* value with the Reason, Description and Origin DevFailed fields properly filled.
Possible errors are:
- Errors coming from the event system for one or more attributes involved in the formula
- Errors coming from evaluation of array with different sizes
- Errors coming from indexes out of bound while extracting elements from arrays
- Unexpected errors while evaluating formulas
File added
File added
File added
File added
File added
File added
docs/images/alarm_manager.png

123 KiB