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 (36)
Showing
with 1102 additions and 419 deletions
image: image:
name: nexus.engageska-portugal.pt/ska-docker/tango-dsconfig 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: stages:
- build - build
...@@ -17,11 +7,11 @@ stages: ...@@ -17,11 +7,11 @@ stages:
build_job: build_job:
stage: build stage: build
tags:
- docker
before_script: 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
- sudo apt update && sudo apt -y --no-install-recommends install build-essential cmake pkg-config libboost-thread-dev procps
script: script:
#- make
- mkdir build && cd build - mkdir build && cd build
- cmake -DBUILD_TESTS=ON .. - cmake -DBUILD_TESTS=ON ..
- make - make
...@@ -33,30 +23,26 @@ build_job: ...@@ -33,30 +23,26 @@ build_job:
test_load_job: test_load_job:
stage: test stage: test
tags:
- docker
before_script: before_script:
#TODO: remove procps use for ps - sudo apt update && sudo apt -y --no-install-recommends install libboost-thread-dev
- sudo apt update && sudo apt -y --no-install-recommends install libboost-thread-dev procps
script: script:
- sleep 10 - sleep 10
- /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 & - /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 &
- sleep 10 - sleep 10
- exit_code=2 - exit_code=2
- json2tango -w -a -u ./test/ah_config.json || exit_code=$? - 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 - if [ ${exit_code} -ne 2 ]; then echo "Tango DB configuration failed!" ; else echo "Tango DB configuration succedeed!"; fi
- sleep 5
- ./build/alarm-handler-srv 01 & - ./build/alarm-handler-srv 01 &
- ./build/bin/testdevice-srv 01 & - ./build/bin/testdevice-srv 01 &
- sleep 10
- ps -ef | grep alarm-handler-srv | grep -v grep
- ps -ef | grep testdevice-srv | grep -v grep
- sleep 5 - 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" - 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 - 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" - 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"] needs: ["build_job"]
services: services:
- name: nexus.engageska-portugal.pt/ska-docker/tango-db - name: harbor.skao.int/production/ska-tango-images-tango-db:10.4.16
alias: tangodb alias: tangodb
image: image:
name: nexus.engageska-portugal.pt/ska-docker/tango-dsconfig name: harbor.skao.int/production/ska-tango-images-tango-dsconfig:1.5.5
# The following variables are automatically passed down to the tangodb container # The following variables are automatically passed down to the tangodb container
# as well as the tangodatabaseds container and available within each. # as well as the tangodatabaseds container and available within each.
...@@ -17,9 +17,9 @@ stages: ...@@ -17,9 +17,9 @@ stages:
- test - test
services: services:
- name: nexus.engageska-portugal.pt/ska-docker/tango-db - name: harbor.skao.int/production/ska-tango-images-tango-db
alias: tangodb alias: tangodb
# - name: nexus.engageska-portugal.pt/ska-docker/tango-cpp # - name: harbor.skao.int/production/ska-tango-images-tango-cpp
# alias: tangodatabaseds # alias: tangodatabaseds
# entrypoint: ["/usr/local/bin/DataBaseds"] # entrypoint: ["/usr/local/bin/DataBaseds"]
# command: ["2","-ORBendPoint giop:tcp::10000"] # command: ["2","-ORBendPoint giop:tcp::10000"]
...@@ -60,7 +60,7 @@ configure_and_run_job: ...@@ -60,7 +60,7 @@ configure_and_run_job:
expire_in: 1 week expire_in: 1 week
needs: ["build_job"] needs: ["build_job"]
#services: #services:
# - name: nexus.engageska-portugal.pt/ska-docker/tango-db # - name: harbor.skao.int/production/ska-tango-images-tango-db
# alias: tangodb # alias: tangodb
test_job: test_job:
......
...@@ -103,11 +103,19 @@ target_include_directories(alarm_handler ...@@ -103,11 +103,19 @@ target_include_directories(alarm_handler
"${PROJECT_BINARY_DIR}" "${PROJECT_BINARY_DIR}"
${Boost_INCLUDE_DIRS}) ${Boost_INCLUDE_DIRS})
set_target_properties(alarm_handler if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
PROPERTIES set_target_properties(alarm_handler
PROPERTIES
OUTPUT_NAME ${AH_NAME} OUTPUT_NAME ${AH_NAME}
LINK_FLAGS "-Wl,--no-undefined" LINK_FLAGS "-Wl,--no-undefined"
CXX_STANDARD 11) CXX_STANDARD 17)
else()
set_target_properties(alarm_handler
PROPERTIES
OUTPUT_NAME ${AH_NAME}
LINK_FLAGS ""
CXX_STANDARD 17)
endif()
if(DO_CLANG_TIDY) if(DO_CLANG_TIDY)
set_target_properties(alarm_handler set_target_properties(alarm_handler
......
File added
# 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
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <AlarmHandler.h> #include <AlarmHandler.h>
#include <AlarmHandlerClass.h> #include <AlarmHandlerClass.h>
#include <ctype.h> //for tolower #include <ctype.h> //for tolower
#include <numeric> //for std::accumulate
#include "alarm-thread.h" #include "alarm-thread.h"
#include "alarm_grammar.h" #include "alarm_grammar.h"
...@@ -372,7 +373,7 @@ void AlarmHandler::init_device() ...@@ -372,7 +373,7 @@ void AlarmHandler::init_device()
if(instanceCounter > 1) if(instanceCounter > 1)
{ {
ERROR_STREAM << "More than one instance in the same executable of Alarm Server is not allowed!!" << endl; ERROR_STREAM << "More than one instance in the same executable of Alarm Server is not allowed!!" << endl;
cout << "ERROR: second instance of Alarm Server, exiting..." << endl; TANGO_LOG << "ERROR: second instance of Alarm Server, exiting..." << endl;
exit(-1); exit(-1);
} //------------------------------------------- } //-------------------------------------------
alarmedlock = new(ReadersWritersLock); alarmedlock = new(ReadersWritersLock);
...@@ -490,6 +491,8 @@ void AlarmHandler::init_device() ...@@ -490,6 +491,8 @@ void AlarmHandler::init_device()
rule_names[formula_grammar::val_qualityID] = "ValQuality"; rule_names[formula_grammar::val_qualityID] = "ValQuality";
rule_names[formula_grammar::val_alarm_enum_stID] = "ValAlarmEnumStatus"; rule_names[formula_grammar::val_alarm_enum_stID] = "ValAlarmEnumStatus";
rule_names[formula_grammar::propertyID] = "EventProperty"; rule_names[formula_grammar::propertyID] = "EventProperty";
rule_names[formula_grammar::index_rangeID] = "RangeIndex";
rule_names[formula_grammar::index_listID] = "ListIndex";
/* /*
* get device attribute properties and initialize internal * get device attribute properties and initialize internal
...@@ -524,7 +527,7 @@ void AlarmHandler::init_device() ...@@ -524,7 +527,7 @@ void AlarmHandler::init_device()
} catch(string & e) } catch(string & e)
{ {
ERROR_STREAM << "AlarmHandler::init_device(): " << e << endl; ERROR_STREAM << "AlarmHandler::init_device(): " << e << endl;
cout << "Error: " << e << ". Exiting..." << endl; TANGO_LOG << "Error: " << e << ". Exiting..." << endl;
exit(-4); exit(-4);
} }
...@@ -1922,13 +1925,13 @@ Tango::DevVarStringArray *AlarmHandler::search_alarm(Tango::DevString argin) ...@@ -1922,13 +1925,13 @@ Tango::DevVarStringArray *AlarmHandler::search_alarm(Tango::DevString argin)
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}*/ }*/
start_pos = filter.find("*", start_pos); start_pos = filter.find("*", start_pos);
if(start_pos != std::string::npos && start_pos == filter.size()-1) //* is the only character or at the end of the filter if(start_pos != std::string::npos && start_pos == filter.size()-1) // * is the only character or at the end of the filter
{ {
filter.replace(start_pos, 1, ""); filter.replace(start_pos, 1, "");
filter_begin = filter; filter_begin = filter;
DEBUG_STREAM << __func__ << ": updated filter to: " << filter_begin; DEBUG_STREAM << __func__ << ": updated filter to: " << filter_begin;
} }
/*else if(start_pos != std::string::npos) //* is in the middle of the filter /*else if(start_pos != std::string::npos) // * is in the middle of the filter
{ {
string filter_begin=filter.substr(0,start_pos); string filter_begin=filter.substr(0,start_pos);
string filter_end=filter.substr(start_pos+1); string filter_end=filter.substr(start_pos+1);
...@@ -1958,7 +1961,7 @@ Tango::DevVarStringArray *AlarmHandler::search_alarm(Tango::DevString argin) ...@@ -1958,7 +1961,7 @@ Tango::DevVarStringArray *AlarmHandler::search_alarm(Tango::DevString argin)
os.clear(); os.clear();
os << KEY(NAME_KEY) << ai->second.name << SEP << KEY(FORMULA_KEY) << ai->second.formula << SEP << KEY(ONDELAY_KEY) << ai->second.on_delay << SEP << KEY(OFFDELAY_KEY) << ai->second.off_delay << os << KEY(NAME_KEY) << ai->second.name << SEP << KEY(FORMULA_KEY) << ai->second.formula << SEP << KEY(ONDELAY_KEY) << ai->second.on_delay << SEP << KEY(OFFDELAY_KEY) << ai->second.off_delay <<
SEP << KEY(LEVEL_KEY) << ai->second.lev << SEP << KEY(SILENT_TIME_KEY) << ai->second.silent_time << SEP << KEY(GROUP_KEY) << ai->second.grp2str() << SEP << KEY(MESSAGE_KEY) << ai->second.msg << SEP << KEY(URL_KEY) << ai->second.url << SEP << KEY(LEVEL_KEY) << ai->second.lev << SEP << KEY(SILENT_TIME_KEY) << ai->second.silent_time << SEP << KEY(GROUP_KEY) << ai->second.grp2str() << SEP << KEY(MESSAGE_KEY) << ai->second.msg << SEP << KEY(URL_KEY) << ai->second.url <<
SEP << KEY(ON_COMMAND_KEY) << ai->second.cmd_name_a << SEP << KEY(OFF_COMMAND_KEY) << ai->second.cmd_name_n << SEP << KEY(ENABLED_KEY) << (ai->second.enabled ? "1" : "0"); SEP << KEY(ON_COMMAND_KEY) << ai->second.cmd_name_a << SEP << KEY(OFF_COMMAND_KEY) << ai->second.cmd_name_n << SEP << KEY(RECEIVERS_KEY) << ai->second.receivers << SEP << KEY(ENABLED_KEY) << (ai->second.enabled ? "1" : "0");
alarm_filtered.push_back(os.str()); alarm_filtered.push_back(os.str());
} }
} /* for */ } /* for */
...@@ -2256,6 +2259,7 @@ void AlarmHandler::modify(Tango::DevString argin) ...@@ -2256,6 +2259,7 @@ void AlarmHandler::modify(Tango::DevString argin)
i->second.cmd_dp_n = alm.cmd_dp_n; i->second.cmd_dp_n = alm.cmd_dp_n;
i->second.cmd_action_n = alm.cmd_action_n; i->second.cmd_action_n = alm.cmd_action_n;
//i->second.send_arg_n = alm.send_arg_n; //i->second.send_arg_n = alm.send_arg_n;
i->second.receivers = alm.receivers;
i->second.enabled = alm.enabled; i->second.enabled = alm.enabled;
//update attribute properties //update attribute properties
...@@ -2353,7 +2357,7 @@ void AlarmHandler::modify(Tango::DevString argin) ...@@ -2353,7 +2357,7 @@ void AlarmHandler::modify(Tango::DevString argin)
//4: load modified alarm //4: load modified alarm
//------------------------------ //------------------------------
load(argin); load(argin);
usleep(150000);//wait some time before updating attributes with prepare_alarm_attr so that event are subscribed and first evaluation done
prepare_alarm_attr(); prepare_alarm_attr();
try try
{ {
...@@ -3033,8 +3037,13 @@ Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarString ...@@ -3033,8 +3037,13 @@ Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarString
if(it->second.error) if(it->second.error)
{ {
tmp_ex << "{\"Reason\":\"" << it->second.ex_reason << "\",\"Desc\":\"" << it->second.ex_desc << "\",\"Origin\":\"" << it->second.ex_origin << "\"}"; tmp_ex << "{\"Reason\":\"" << it->second.ex_reason << "\",\"Desc\":\"" << it->second.ex_desc << "\",\"Origin\":\"" << it->second.ex_origin << "\"}";
info.insert(make_pair(VALUE_KEY,string("ERROR"))); string almstate(tmp_val.str());
complete.push_back(KEY(VALUE_KEY)+string("ERROR")); if(almstate != "SHLVD" && almstate != "OOSRV")
{
almstate = S_ERROR;
}
info.insert(make_pair(VALUE_KEY,almstate));
complete.push_back(KEY(VALUE_KEY)+almstate);
info.insert(make_pair(MESSAGE_KEY,tmp.str())); info.insert(make_pair(MESSAGE_KEY,tmp.str()));
complete.push_back(KEY(MESSAGE_KEY)+tmp.str()); complete.push_back(KEY(MESSAGE_KEY)+tmp.str());
info.insert(make_pair(URL_KEY,it->second.url)); info.insert(make_pair(URL_KEY,it->second.url));
...@@ -3058,6 +3067,17 @@ Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarString ...@@ -3058,6 +3067,17 @@ Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarString
complete.push_back(KEY(ATTR_VALUES_KEY)+it->second.attr_values); complete.push_back(KEY(ATTR_VALUES_KEY)+it->second.attr_values);
} }
tm time_tm;
time_t time_sec= it->second.ts.tv_sec;
//gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm);
char time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
ostringstream time_s;
time_s << time_buf << "." << it->second.ts.tv_usec;
info.insert(make_pair(ALARM_TIME_KEY,time_s.str()));
complete.push_back(KEY(ALARM_TIME_KEY)+time_s.str());
ostringstream tmp_qual; ostringstream tmp_qual;
try try
{ {
...@@ -3128,7 +3148,8 @@ Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarString ...@@ -3128,7 +3148,8 @@ Tango::DevVarStringArray *AlarmHandler::get_alarm_info(const Tango::DevVarString
complete.push_back(KEY(ON_COMMAND_KEY)+it->second.cmd_name_a); complete.push_back(KEY(ON_COMMAND_KEY)+it->second.cmd_name_a);
info.insert(make_pair(OFF_COMMAND_KEY,it->second.cmd_name_n)); info.insert(make_pair(OFF_COMMAND_KEY,it->second.cmd_name_n));
complete.push_back(KEY(OFF_COMMAND_KEY)+it->second.cmd_name_n); complete.push_back(KEY(OFF_COMMAND_KEY)+it->second.cmd_name_n);
info.insert(make_pair(RECEIVERS_KEY,it->second.receivers));
complete.push_back(KEY(RECEIVERS_KEY)+it->second.receivers);
alarms.vlock->readerOut(); alarms.vlock->readerOut();
argout = new Tango::DevVarStringArray(); argout = new Tango::DevVarStringArray();
if(argin->length() == 1) if(argin->length() == 1)
...@@ -3258,6 +3279,7 @@ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string> ...@@ -3258,6 +3279,7 @@ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string>
alm.send_arg_n = false; alm.send_arg_n = false;
alm.dp_n = NULL; alm.dp_n = NULL;
alm.enabled = 1; alm.enabled = 1;
alm.receivers.clear();
evn.clear(); evn.clear();
alm.formula_tree = alm.formula_tree =
...@@ -3278,6 +3300,7 @@ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string> ...@@ -3278,6 +3300,7 @@ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string>
std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase
alm.msg = std::regex_replace(alm.msg, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";" alm.msg = std::regex_replace(alm.msg, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
alm.url = std::regex_replace(alm.url, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";" alm.url = std::regex_replace(alm.url, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
alm.receivers = std::regex_replace(alm.receivers, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
if(alm.cmd_name_a.length() > 0) if(alm.cmd_name_a.length() > 0)
{ {
const char *c = alm.cmd_name_a.c_str(); const char *c = alm.cmd_name_a.c_str();
...@@ -3342,6 +3365,7 @@ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string> ...@@ -3342,6 +3365,7 @@ void AlarmHandler::load_alarm(string alarm_string, alarm_t &alm, vector<string>
DEBUG_STREAM << " lev = '" << alm.lev << "'" << endl; DEBUG_STREAM << " lev = '" << alm.lev << "'" << endl;
DEBUG_STREAM << " action_a = '" << alm.cmd_name_a << "'" << endl; DEBUG_STREAM << " action_a = '" << alm.cmd_name_a << "'" << endl;
DEBUG_STREAM << " action_n = '" << alm.cmd_name_n << "'" << endl; DEBUG_STREAM << " action_n = '" << alm.cmd_name_n << "'" << endl;
DEBUG_STREAM << " receivers = '" << alm.receivers << "'" << endl;
DEBUG_STREAM << " enabled = '" << (alm.enabled ? "1" : "0") << "'" << endl; DEBUG_STREAM << " enabled = '" << (alm.enabled ? "1" : "0") << "'" << endl;
if ((alm.name.empty() == false) && \ if ((alm.name.empty() == false) && \
(alm.formula.empty() == false) && \ (alm.formula.empty() == false) && \
...@@ -3448,7 +3472,7 @@ void AlarmHandler::add_alarm(alarm_t& a, bool starting) ...@@ -3448,7 +3472,7 @@ void AlarmHandler::add_alarm(alarm_t& a, bool starting)
} }
} }
void AlarmHandler::add_event(alarm_t& a, vector<string> &evn) throw(string&) void AlarmHandler::add_event(alarm_t& a, vector<string> &evn)
{ {
DEBUG_STREAM << "AlarmHandler::add_event(): formula '" << a.formula << "' found " << evn.size() << " events" << endl; DEBUG_STREAM << "AlarmHandler::add_event(): formula '" << a.formula << "' found " << evn.size() << " events" << endl;
/* /*
...@@ -3636,6 +3660,7 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3636,6 +3660,7 @@ void AlarmHandler::do_alarm(bei_t& e)
} }
if(found_ev != events->v_event.end()) if(found_ev != events->v_event.end())
{ {
found_ev->valid = false;
Tango::TimeVal ts = gettime(); Tango::TimeVal ts = gettime();
found_ev->err_counter++; found_ev->err_counter++;
if(e.type == TYPE_TANGO_ERR) if(e.type == TYPE_TANGO_ERR)
...@@ -3654,10 +3679,15 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3654,10 +3679,15 @@ void AlarmHandler::do_alarm(bei_t& e)
list<string>::iterator j = m_alarm.begin(); list<string>::iterator j = m_alarm.begin();
while (j != m_alarm.end()) while (j != m_alarm.end())
{ {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": before do_alarm_eval name=" << *j << " ev=" << e.ev_name << " err=" << found_ev_ex_desc << endl;
changed = do_alarm_eval(*j, e.ev_name, ts);
//if(!changed)
// continue; //TODO: check if OK
alarms.vlock->readerIn(); alarms.vlock->readerIn();
alarm_container_t::iterator it = alarms.v_alarm.find(*j); alarm_container_t::iterator it = alarms.v_alarm.find(*j);
if(it != alarms.v_alarm.end()) if(it != alarms.v_alarm.end())
{ {
#if 0 //already done in alarm_table::update called by do_alarm_eval
it->second.err_counter++; it->second.err_counter++;
//if first error, reset ACK //if first error, reset ACK
if(it->second.ex_reason.empty() && it->second.ex_desc.empty() && it->second.ex_origin.empty()) if(it->second.ex_reason.empty() && it->second.ex_desc.empty() && it->second.ex_origin.empty())
...@@ -3691,8 +3721,11 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3691,8 +3721,11 @@ void AlarmHandler::do_alarm(bei_t& e)
} }
it->second.error = true; it->second.error = true;
} }
#endif
alarm_t alm = it->second; alarm_t alm = it->second;
alarms.vlock->readerOut(); alarms.vlock->readerOut();
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": after do_alarm_eval name=" << *j << " error=" << (int)alm.error << " enabled=" << alm.enabled << endl;
#if 0 //TODO: already pushed in do_alarm_eval, not necessary here ?
if(alm.error && alm.enabled && !(alm.shelved && alm.silenced > 0)) if(alm.error && alm.enabled && !(alm.shelved && alm.silenced > 0))
{ {
try try
...@@ -3710,7 +3743,7 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3710,7 +3743,7 @@ void AlarmHandler::do_alarm(bei_t& e)
}catch(Tango::DevFailed &ex) }catch(Tango::DevFailed &ex)
{} {}
} }
else else if(alm.error) //TODO: or if(changed) ?
{ {
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name); Tango::DevEnum *attr_value = get_AlarmState_data_ptr(alm.attr_name);
if(!alm.enabled) if(!alm.enabled)
...@@ -3734,6 +3767,7 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3734,6 +3767,7 @@ void AlarmHandler::do_alarm(bei_t& e)
push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value); push_archive_event(alm.attr_name,(Tango::DevEnum *)attr_value);
} }
} }
#endif
} }
else else
{ {
...@@ -3781,10 +3815,14 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3781,10 +3815,14 @@ void AlarmHandler::do_alarm(bei_t& e)
push_archive_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz); push_archive_event("alarmSummary",attr_alarmSummary_read, alarmSummary_sz);
push_archive_event("alarmDisabled",attr_alarmDisabled_read, alarmDisabled_sz); push_archive_event("alarmDisabled",attr_alarmDisabled_read, alarmDisabled_sz);
} }
else
{
events->veclock.readerOut();
}
return; return;
} }
//here not event error
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": arrived event=" << e.ev_name << endl; DEBUG_STREAM << "AlarmHandler::"<<__func__<<": arrived event=" << e.ev_name << endl;
formula_res_t res;
events->veclock.readerIn(); events->veclock.readerIn();
vector<event>::iterator found = \ vector<event>::iterator found = \
find(events->v_event.begin(), events->v_event.end(), e.ev_name); find(events->v_event.begin(), events->v_event.end(), e.ev_name);
...@@ -3828,9 +3866,12 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3828,9 +3866,12 @@ void AlarmHandler::do_alarm(bei_t& e)
} }
} }
if (found != events->v_event.end()) if (found != events->v_event.end())
{ {
found->value = e.value; found->value = e.value;
found->value_string = e.value_string; found->value_string = e.value_string;
found->read_size = e.read_size;
found->dim_x = e.dim_x;
found->dim_y = e.dim_y;
found->quality = e.quality; found->quality = e.quality;
//found->errors = e.errors; //found->errors = e.errors;
found->ex_reason = e.ex_reason; found->ex_reason = e.ex_reason;
...@@ -3913,6 +3954,7 @@ void AlarmHandler::do_alarm(bei_t& e) ...@@ -3913,6 +3954,7 @@ void AlarmHandler::do_alarm(bei_t& e)
} }
else else
{ {
events->veclock.readerOut();
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event=" << e.ev_name << "NOT FOUND IN EVENT TABLE" << endl; DEBUG_STREAM << "AlarmHandler::"<<__func__<<": event=" << e.ev_name << "NOT FOUND IN EVENT TABLE" << endl;
} }
} /* do_alarm() */ } /* do_alarm() */
...@@ -3952,10 +3994,10 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ...@@ -3952,10 +3994,10 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal
it->second.to_be_evaluated = false; it->second.to_be_evaluated = false;
it->second.attr_values.erase(it->second.attr_values.size()-1); it->second.attr_values.erase(it->second.attr_values.size()-1);
it->second.attr_values += string("}"); it->second.attr_values += string("}");
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << res.value << " quality=" << res.quality << endl; DEBUG_STREAM << "AlarmHandler::"<<__func__<<": Evaluation of " << it->second.formula << "; result=" << print_array(res.value,res.dim_x,res.dim_y) << " quality=" << res.quality << " valid=" << (int)res.valid << endl;
changed = alarms.update(tmpname, ts, res, it->second.attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db changed = alarms.update(tmpname, ts, res, it->second.attr_values, it->second.grp2str(), it->second.msg, it->second.formula); //update internal structure and log to db
changed = changed || prev_error; changed = changed || (prev_error && res.valid);
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": changed=" << (int)changed << endl; DEBUG_STREAM << "AlarmHandler::"<<__func__<<": changed=" << (int)changed << " error=" << (int)it->second.error << endl;
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name); Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name);
if(!it->second.enabled) if(!it->second.enabled)
*attr_value = _OOSRV; *attr_value = _OOSRV;
...@@ -4009,7 +4051,8 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ...@@ -4009,7 +4051,8 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal
} }
} catch(std::out_of_range& ex) } catch(std::out_of_range& ex)
{ {
changed = !prev_error; events->veclock.readerOut(); //readerIn called in eval_expression
changed = true;//force update attributes in case of modify/load alarm with out_of_range exception
it->second.to_be_evaluated = true; it->second.to_be_evaluated = true;
ostringstream o; ostringstream o;
o << tmpname << ": in formula array index out of range!"; o << tmpname << ": in formula array index out of range!";
...@@ -4020,7 +4063,7 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ...@@ -4020,7 +4063,7 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal
Tango::DevErrorList errors(1); Tango::DevErrorList errors(1);
errors.length(1); errors.length(1);
it->second.ex_reason = string("OUT_OF_RANGE"); it->second.ex_reason = string("OUT_OF_RANGE");
it->second.ex_desc = ev_name + ": " + o.str(); it->second.ex_desc = o.str();
it->second.ex_origin = ev_name; it->second.ex_origin = ev_name;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str()); errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR; errors[0].severity = Tango::ERR;
...@@ -4030,6 +4073,13 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ...@@ -4030,6 +4073,13 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal
bool enabled=it->second.enabled; bool enabled=it->second.enabled;
bool shelved=it->second.shelved; bool shelved=it->second.shelved;
int silenced=it->second.silenced; int silenced=it->second.silenced;
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name);
it->second.error=true;
it->second.quality = Tango::ATTR_INVALID;
if(enabled && !(shelved && silenced >0))
{
*attr_value = _ERROR;
}
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
if(enabled && !(shelved && silenced >0)) if(enabled && !(shelved && silenced >0))
{ {
...@@ -4063,6 +4113,54 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ...@@ -4063,6 +4113,54 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal
bool enabled=it->second.enabled; bool enabled=it->second.enabled;
bool shelved=it->second.shelved; bool shelved=it->second.shelved;
int silenced=it->second.silenced; int silenced=it->second.silenced;
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name);
it->second.error=true;
it->second.quality = Tango::ATTR_INVALID;
if(enabled && !(shelved && silenced >0))
{
*attr_value = _ERROR;
}
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
if(enabled && !(shelved && silenced >0))
{
push_change_event(attr_name, &except);
push_archive_event(attr_name, &except);
}
} catch(Tango::DevFailed & ex)
{
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << attr_name << " - EXCEPTION PUSHING EVENTS: " << ex.errors[0].desc << endl;
}
}
catch(Tango::DevFailed & ex)
{
changed = !prev_error;
it->second.to_be_evaluated = true;
ostringstream o;
o << ex.errors[0].desc;
WARN_STREAM << "AlarmHandler::"<<__func__<<": " << o.str() << endl;
set_internal_alarm(INTERNAL_ERROR, gettime(), o.str());
try
{ //DevFailed for push events
Tango::DevErrorList errors(1);
errors.length(1);
it->second.ex_reason = ex.errors[0].reason;
it->second.ex_desc = ex.errors[0].desc;
it->second.ex_origin = ex.errors[0].origin;
errors[0].desc = CORBA::string_dup(it->second.ex_desc.c_str());
errors[0].severity = Tango::ERR;
errors[0].reason = CORBA::string_dup(it->second.ex_reason.c_str());
errors[0].origin = CORBA::string_dup(it->second.ex_origin.c_str());
Tango::DevFailed except(errors);
bool enabled=it->second.enabled;
bool shelved=it->second.shelved;
int silenced=it->second.silenced;
Tango::DevEnum *attr_value = get_AlarmState_data_ptr(attr_name);
it->second.error=true;
it->second.quality = Tango::ATTR_INVALID;
if(enabled && !(shelved && silenced >0))
{
*attr_value = _ERROR;
}
alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks alarms.vlock->readerOut(); //Don't hold alarms lock while pushing events to prevent deadlocks
if(enabled && !(shelved && silenced >0)) if(enabled && !(shelved && silenced >0))
{ {
...@@ -4077,6 +4175,7 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal ...@@ -4077,6 +4175,7 @@ bool AlarmHandler::do_alarm_eval(string alm_name, string ev_name, Tango::TimeVal
} }
else else
{ {
alarms.vlock->readerOut();
ostringstream o; ostringstream o;
//o << j->first << ": not found formula in alarm table" << ends; //o << j->first << ": not found formula in alarm table" << ends;
o << (alm_name) << ": not found formula in alarm table"; o << (alm_name) << ": not found formula in alarm table";
...@@ -4137,6 +4236,7 @@ void AlarmHandler::timer_update() ...@@ -4137,6 +4236,7 @@ void AlarmHandler::timer_update()
{ {
return; return;
} }
DEBUG_STREAM << "AlarmHandler::timer_update(): changed -> prepare_alarm_attr" << endl;
prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway prepare_alarm_attr();//TODO: frequencyAlarm should be updated anyway
try try
{ {
...@@ -4186,7 +4286,7 @@ void AlarmHandler::timer_update() ...@@ -4186,7 +4286,7 @@ void AlarmHandler::timer_update()
} }
} }
bool AlarmHandler::remove_alarm(string& s) throw(string&) bool AlarmHandler::remove_alarm(string& s)
{ {
DEBUG_STREAM << "AlarmHandler::"<<__func__<<": entering alm name=" << s << endl; DEBUG_STREAM << "AlarmHandler::"<<__func__<<": entering alm name=" << s << endl;
alarms.vlock->writerIn(); alarms.vlock->writerIn();
...@@ -4296,7 +4396,7 @@ bool AlarmHandler::remove_alarm(string& s) throw(string&) ...@@ -4296,7 +4396,7 @@ bool AlarmHandler::remove_alarm(string& s) throw(string&)
} /* remove_alarm() */ } /* remove_alarm() */
/*void AlarmHandler::add_to_database(alarm_t& a) throw(string&) /*void AlarmHandler::add_to_database(alarm_t& a)
{ {
Tango::DbDatum alarm("alarm"); Tango::DbDatum alarm("alarm");
Tango::DbData db_data; Tango::DbData db_data;
...@@ -4421,10 +4521,55 @@ void AlarmHandler::set_internal_alarm(string name, Tango::TimeVal t, string msg, ...@@ -4421,10 +4521,55 @@ void AlarmHandler::set_internal_alarm(string name, Tango::TimeVal t, string msg,
//============================================================== //==============================================================
formula_res_t AlarmHandler::eval_formula(tree_parse_info_t tree, string &attr_values) formula_res_t AlarmHandler::eval_formula(tree_parse_info_t tree, string &attr_values)
{ {
return eval_expression(tree.trees.begin(), attr_values); formula_res_t res = eval_expression(tree.trees.begin(), attr_values);
res.extract_result(); //from Array res.value to Scalar res.value
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << __func__ << ": finally value=" << print_array(res.value,res.dim_x,res.dim_y) << " valid=" << (int)res.valid << " error='" << res.error << "' ex_desc='" << res.ex_desc<<"' quality=" << res.quality << endl;
#endif
if(res.valid)
{
res.ex_reason.clear();
res.ex_desc.clear();
res.ex_origin.clear();
res.error.clear();
}
return res;
}
void AlarmHandler::eval_index_range(iter_t const& i, string &attr_values, vector<double> & ind)
{
if(i->value.id() == formula_grammar::index_rangeID || i->value.id() == formula_grammar::indexID)
{
if(i->children.size() == 0)
{
std::string val_s(i->value.begin(), i->value.end());
long value = strtol(val_s.c_str(), NULL, 10);
if(value>=0)
{
ind.push_back(value);
}
else if(value == -1)
{
ind = {(double)(value)};
}
}
else if(i->children.size() == 2)
{
iter_t child = i->children.begin();
string val_s1(child->value.begin(), child->value.end());
long ind_start = strtol(val_s1.c_str(), NULL, 10);
string val_s2((child+1)->value.begin(), (child+1)->value.end());
long ind_end = strtol(val_s2.c_str(), NULL, 10);
if(ind_start>=0 && ind_end>=ind_start)
{
for(int ind_range=ind_start; ind_range<=ind_end; ind_range++)
ind.push_back((double)ind_range);
}
}
}
} }
formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values, int ev_ind) //throw (string &), std::out_of_range formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values, vector< vector<double> > ev_ind)
{ {
ostringstream err; ostringstream err;
...@@ -4440,9 +4585,12 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4440,9 +4585,12 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
} }
string val_d(i->value.begin(), i->value.end()); string val_d(i->value.begin(), i->value.end());
formula_res_t res; formula_res_t res;
res.value = strtod(val_d.c_str(), 0); res.value = {(strtod(val_d.c_str(), 0))};
res.dim_x=1;
res.dim_y=0;
res.valid = true;
#ifdef _DEBUG_FORMULA #ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node value real = " << val_d << "(value="<<res.value<<" quality="<<res.quality<<")" << endl; DEBUG_STREAM << " node value real = " << val_d << "(value="<<print_array(res.value,res.dim_x,res.dim_y)<<" quality="<<res.quality<<")" << endl;
#endif #endif
return res; return res;
} }
...@@ -4458,7 +4606,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4458,7 +4606,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
DEBUG_STREAM << " node value hex = " << val_d << endl; DEBUG_STREAM << " node value hex = " << val_d << endl;
#endif #endif
formula_res_t res; formula_res_t res;
res.value = strtod(val_d.c_str(), 0); res.value = {(strtod(val_d.c_str(), 0))};
res.dim_x=1;
res.dim_y=0;
res.valid = true;
return res; return res;
} }
else if (i->value.id() == formula_grammar::val_stID) else if (i->value.id() == formula_grammar::val_stID)
...@@ -4474,7 +4625,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4474,7 +4625,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
DEBUG_STREAM << " node value state : " << val_st << "=" << st << endl; DEBUG_STREAM << " node value state : " << val_st << "=" << st << endl;
#endif #endif
formula_res_t res; formula_res_t res;
res.value = st; res.value = {(double)st};
res.dim_x=1;
res.dim_y=0;
res.valid = true;
return res; return res;
} }
else if (i->value.id() == formula_grammar::val_alarm_enum_stID) else if (i->value.id() == formula_grammar::val_alarm_enum_stID)
...@@ -4490,7 +4644,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4490,7 +4644,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
DEBUG_STREAM << " node value alarm enum state : " << val_st << "=" << st << endl; DEBUG_STREAM << " node value alarm enum state : " << val_st << "=" << st << endl;
#endif #endif
formula_res_t res; formula_res_t res;
res.value = st; res.value = {(double)st};
res.dim_x=1;
res.dim_y=0;
res.valid = true;
return res; return res;
} }
else if (i->value.id() == formula_grammar::val_qualityID) else if (i->value.id() == formula_grammar::val_qualityID)
...@@ -4507,7 +4664,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4507,7 +4664,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
DEBUG_STREAM << " node value quality : " << val_quality << "=" << quality << endl; DEBUG_STREAM << " node value quality : " << val_quality << "=" << quality << endl;
#endif #endif
formula_res_t res; formula_res_t res;
res.value = quality; res.value = {(double)quality};
res.dim_x=1;
res.dim_y=0;
res.valid = true;
return res; return res;
} }
else if (i->value.id() == formula_grammar::unary_exprID) else if (i->value.id() == formula_grammar::unary_exprID)
...@@ -4520,26 +4680,23 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4520,26 +4680,23 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
err << "in node unary_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size(); err << "in node unary_exprID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size();
throw err.str(); throw err.str();
} }
formula_res_t res;
res = eval_expression(i->children.begin(), attr_values);
if (*i->value.begin() == '+') if (*i->value.begin() == '+')
{ {
res.value = + res.value; return eval_expression(i->children.begin(), attr_values);
} }
else if (*i->value.begin() == '-') else if (*i->value.begin() == '-')
{ {
res.value = - res.value; return -eval_expression(i->children.begin(), attr_values);
} }
else if (*i->value.begin() == '!') else if (*i->value.begin() == '!')
{ {
res.value = ! res.value; return !eval_expression(i->children.begin(), attr_values);
} }
else else
{ {
err << "in node unary_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; err << "in node unary_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed";
throw err.str(); throw err.str();
} }
return res;
} }
else if (i->value.id() == formula_grammar::mult_exprID) else if (i->value.id() == formula_grammar::mult_exprID)
{ {
...@@ -4599,49 +4756,104 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4599,49 +4756,104 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
DEBUG_STREAM << " node event" << string(i->value.begin(), i->value.end()) << endl; DEBUG_STREAM << " node event" << string(i->value.begin(), i->value.end()) << endl;
#endif #endif
formula_res_t ind; formula_res_t ind;
if(i->children.size() != 2) if(i->children.size() < 2)
{ {
err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size();; err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size();;
throw err.str(); throw err.str();
} }
if((i->children.begin()+1)->value.id() == formula_grammar::indexID) vector<vector<double> > indexes;
ind = eval_expression(i->children.begin()+1, attr_values); //array index iter_t child = i->children.begin();
else if((i->children.begin()+1)->value.id() == formula_grammar::propertyID) if(child->value.id() != formula_grammar::nameID)
{ {
if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".quality") err << "in node "<< rule_names[i->value.id()]<<"(" << string(i->value.begin(), i->value.end()) << ") expecting " << rule_names[formula_grammar::nameID] << " as first child";
throw err.str();
}
child++;
while(child != i->children.end() && child->value.id() != formula_grammar::propertyID) //eval indexes
{
if(child->value.id() == formula_grammar::index_rangeID || child->value.id() == formula_grammar::indexID)
{ {
formula_res_t res = eval_expression(i->children.begin(), attr_values, (int)ind.value); vector<double> ind_range;
res.value = res.quality; eval_index_range(child, attr_values, ind_range);
if(!ind_range.empty())
indexes.push_back(ind_range);
}
else if(child->value.id() == formula_grammar::index_listID)
{
vector<double> ind_list;
iter_t granchild = child->children.begin();
while(granchild != child->children.end() && granchild->value.id() == formula_grammar::index_rangeID) //eval indexes
{
eval_index_range(granchild, attr_values, ind_list);
granchild++;
}
if(!ind_list.empty())
indexes.push_back(ind_list);
}
child++;
}
if(child - i->children.begin() == (long int)i->children.size() -1 && child->value.id() == formula_grammar::propertyID)
{
if(string(child->value.begin(), child->value.end()) == ".quality")
{
formula_res_t res;
res = eval_expression(i->children.begin(), attr_values);
res.value = {(double)res.quality};
res.dim_x=1;
res.dim_y=0;
ostringstream temp_attr_val;
temp_attr_val << "\"" << res.attr_name << string(child->value.begin(), child->value.end()) << "\":" <<print_array(res.value,res.dim_x,res.dim_y) << ",";
attr_values += temp_attr_val.str();
#ifdef _DEBUG_FORMULA #ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node event.quality -> " << res.value << endl; DEBUG_STREAM << " node event.quality -> " << print_array(res.value,res.dim_x,res.dim_y) << endl;
#endif #endif
return res; return res;
} }
else if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".alarm") else if(string(child->value.begin(), child->value.end()) == ".alarm")
{ {
formula_res_t res = eval_expression(i->children.begin(), attr_values, (int)ind.value); formula_res_t res;
res.value = (res.value == _UNACK) || (res.value == _ACKED); if(!indexes.empty())
res = eval_expression(i->children.begin(), attr_values, indexes);
else
res = eval_expression(i->children.begin(), attr_values);
std::transform(res.value.begin(), res.value.end(), res.value.begin(),
[](double n) { return (double)((n == _UNACK) || (n == _ACKED)); });
ostringstream temp_attr_val;
temp_attr_val << "\"" << res.attr_name << string(child->value.begin(), child->value.end()) << "\":" <<print_array(res.value,res.dim_x,res.dim_y) << ",";
attr_values += temp_attr_val.str();
#ifdef _DEBUG_FORMULA #ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node event.alarm -> " << res.value << endl; DEBUG_STREAM << " node event.alarm -> " << print_array(res.value,res.dim_x,res.dim_y)<< endl;
#endif #endif
return res; return res;
} }
else if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".normal") else if(string(child->value.begin(), child->value.end()) == ".normal")
{ {
formula_res_t res = eval_expression(i->children.begin(), attr_values, (int)ind.value); formula_res_t res;
res.value = (res.value == _NORM) || (res.value == _RTNUN); if(!indexes.empty())
res = eval_expression(i->children.begin(), attr_values, indexes);
else
res = eval_expression(i->children.begin(), attr_values);
std::transform(res.value.begin(), res.value.end(), res.value.begin(),
[](double n) { return (double)((n == _NORM) || (n == _RTNUN)); });
ostringstream temp_attr_val;
temp_attr_val << "\"" << res.attr_name << string(child->value.begin(), child->value.end()) << "\":" <<print_array(res.value,res.dim_x,res.dim_y) << ",";
attr_values += temp_attr_val.str();
#ifdef _DEBUG_FORMULA #ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node event.normal -> " << res.value << endl; DEBUG_STREAM << " node event.normal -> " << print_array(res.value,res.dim_x,res.dim_y) << endl;
#endif #endif
return res; return res;
} }
} }
else else if(child - i->children.begin() < (long int)i->children.size() -1)//unsupported more indexes/qualities
{ {
err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children2 is not an index ->" << string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()); err << "expecting indexes or properties after attribute name, found instead: "<< string(child->value.begin(), child->value.end());
throw err.str(); throw err.str();
} }
return eval_expression(i->children.begin(), attr_values, (int)ind.value); if(!indexes.empty())
return eval_expression(i->children.begin(), attr_values, indexes);
else
return eval_expression(i->children.begin(), attr_values);
} }
else if (i->value.id() == formula_grammar::nameID) else if (i->value.id() == formula_grammar::nameID)
{ {
...@@ -4664,8 +4876,25 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4664,8 +4876,25 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
err << it->ex_desc << ""; err << it->ex_desc << "";
else else
err << "attribute " << string(i->value.begin(), i->value.end()) << " value not valid while evaluating formula"; err << "attribute " << string(i->value.begin(), i->value.end()) << " value not valid while evaluating formula";
formula_res_t res;
res.valid = false;
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.quality = it->quality;
res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc;
res.ex_origin = it->ex_origin;
res.error = err.str();
res.attr_name = it->name;
ostringstream temp_attr_val;
temp_attr_val << "\"" << it->name << "\":{\"Reason\":\"" << res.ex_reason << "\",\"Desc\":\"" << res.ex_desc << "\",\"Origin\":\"" << res.ex_origin << "\"},";
attr_values += temp_attr_val.str();
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << " attribute -> " << string(i->value.begin(), i->value.end()) << " value not valid, desc=" << res.ex_desc << " quality=" << res.quality << endl;
#endif
events->veclock.readerOut(); events->veclock.readerOut();
throw err.str(); //throw err.str();
return res;
} }
else if(it->type != Tango::DEV_STRING && it->value.empty()) else if(it->type != Tango::DEV_STRING && it->value.empty())
{ {
...@@ -4673,25 +4902,383 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4673,25 +4902,383 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
err << it->ex_desc << ""; err << it->ex_desc << "";
else else
err << "attribute " << string(i->value.begin(), i->value.end()) << " value not initialized while evaluating formula"; err << "attribute " << string(i->value.begin(), i->value.end()) << " value not initialized while evaluating formula";
formula_res_t res;
res.valid = false;
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.quality = it->quality;
res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc;
res.ex_origin = it->ex_origin;
res.error = err.str();
res.attr_name = it->name;
ostringstream temp_attr_val;
temp_attr_val << "\"" << it->name << "\":{\"Reason\":\"" << res.ex_reason << "\",\"Desc\":\"" << res.ex_desc << "\",\"Origin\":\"" << res.ex_origin << "\"},";
attr_values += temp_attr_val.str();
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << " attribute -> " << string(i->value.begin(), i->value.end()) << " value empty, desc=" << res.ex_desc << " quality=" << res.quality << endl;
#endif
events->veclock.readerOut(); events->veclock.readerOut();
throw err.str(); //throw err.str();
} return res;
ostringstream temp_attr_val; }
if(it->value.size() > 1)
temp_attr_val << "\"" << it->name << "[" << ev_ind << "]\":" <<it->value.at(ev_ind) << ",";//throw std::out_of_range
else
temp_attr_val << "\"" << it->name << "\":" <<it->value.at(ev_ind) << ",";//throw std::out_of_range
attr_values += temp_attr_val.str();
formula_res_t res; formula_res_t res;
res.valid = true;
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.quality = it->quality; res.quality = it->quality;
res.ex_reason = it->ex_reason; res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc; res.ex_desc = it->ex_desc;
res.ex_origin = it->ex_origin; res.ex_origin = it->ex_origin;
res.attr_name = it->name;
ostringstream temp_attr_val;
if(it->value.size() > 0)
{
if(!ev_ind.empty())
{
temp_attr_val << "\"" << it->name;
for(auto vei : ev_ind)
{
if(!vei.empty())
{
temp_attr_val << "[" << print_vector(vei) << "]";
}
}
temp_attr_val << "\":";
if(it->dim_y <=1)//1D array
{
if(ev_ind.size() ==1 && ev_ind[0].size() == 1 && ev_ind[0][0] != -1)//single element of 1D array (e.g. [0])
{
res.dim_x = 1;
res.dim_y = 0;
if(ev_ind[0][0] >= it->value.size())
{
err << "Requested element " << ev_ind[0][0] << " is out of bounds with dim=" << it->value.size();
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
res.value = {it->value.at(ev_ind[0][0])};//throw std::out_of_range
temp_attr_val << "[" << res.value[0] << "],";
}
else if(ev_ind.size() ==1 && ev_ind[0].size() > 1)//multiple elements of 1D array (e.g. [0,1,2])
{
res.dim_y = 0;
for(auto ei0 : ev_ind[0])
{
if(ei0 < 0 || ei0 >= it->value.size())
{
err << "Requested element " << ei0 << " is out of bounds with dim=" << it->value.size();
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
else
{
res.value.push_back(it->value.at(ei0));//throw std::out_of_range
}
}
res.dim_x = res.value.size();
temp_attr_val << print_array(res.value, res.dim_x, res.dim_y) << ",";
}
else if(ev_ind.size() ==1 && ev_ind[0].size() == 1 && ev_ind[0][0]==-1)//all elements of 1D array (e.g. [-1])
{
res.dim_y = 0;
res.value = it->value;
res.dim_x = it->dim_x;
temp_attr_val << print_array(res.value, res.dim_x, res.dim_y) <<",";
}
else
{
err << "UNSUPPORTED additional indexes in 1D array: " << ev_ind.size() << " indexes given, dim_x=" << it->dim_x << " dim_y=" << it->dim_y;
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
events->veclock.readerOut();
throw err.str();
}
}
else if(it->dim_y > 1)//2D array
{
//single row of 2D array (e.g. [0] or [0][-1])
if((ev_ind.size() == 1 || //only first index
(ev_ind.size() == 2 && ev_ind[1].size() == 1 && ev_ind[1][0] == -1)) //or also second index = -1
&& ev_ind[0].size() == 1 && ev_ind[0][0] != -1) // and first index not -1
{
res.dim_y = 0;
if(ev_ind[0][0] >= it->dim_y)
{
err << "Requested row " << ev_ind[0][0] << " is out of bounds with dim_y=" << it->dim_y;
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
auto vstart = it->value.begin();//start iterator of a row in a vector containing a 2D array
auto vend = it->value.begin();//end iterator of a row in a vector containing a 2D array
advance(vstart,(int)(ev_ind[0][0] * (it->dim_x)));
advance(vend,(int)(ev_ind[0][0]+1) * it->dim_x);
res.value = value_t(vstart,vend);
temp_attr_val << "" << print_array(res.value,res.dim_x,res.dim_y) << ",";
}
else if((ev_ind.size() == 1 || //only first index
(ev_ind.size() == 2 && ev_ind[1].size() == 1 && ev_ind[1][0] == -1)) //or also second index = -1
&& ev_ind[0].size() > 1)//multiple rows of 2D array (e.g. [0,1,2] or [0,1,2][-1])
{
res.dim_x = it->dim_x;
res.dim_y = ev_ind[0].size();
for(auto ei0 : ev_ind[0])
{
if(ei0 < 0 || ei0 >= it->value.size())
{
err << "Requested element " << ei0 << " is out of bounds with dim=" << it->value.size();
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
else
{
auto vstart = it->value.begin();//start iterator of a row in a vector containing a 2D array
auto vend = it->value.begin();//end iterator of a row in a vector containing a 2D array
advance(vstart,(int)(ei0 * (it->dim_x)));
advance(vend,(int)(ei0+1) * it->dim_x);
value_t row = value_t(vstart,vend);
res.value.insert(
res.value.end(),
std::make_move_iterator(row.begin()),
std::make_move_iterator(row.end())
);
}
}
temp_attr_val << print_array(res.value,res.dim_x,res.dim_y) << ",";
}
else if((ev_ind.size() == 1 || //only first index
(ev_ind.size() == 2 && ev_ind[1].size() == 1 && ev_ind[1][0] == -1)) //or also second index = -1
&& ev_ind[0].size() == 1 && ev_ind[0][0] == -1)//all rows of 2D array (e.g. [-1] or [-1][-1])
{
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.value = it->value;
temp_attr_val << print_array(res.value,res.dim_x,res.dim_y) << ",";
}
else if(ev_ind.size() == 2 && ev_ind[0].size() == 1 && ev_ind[0][0] != -1 && ev_ind[1].size() == 1 && ev_ind[1][0] != -1)//single element of 2D array (e.g. [0][1])
{
res.dim_x = 1;
res.dim_y = 0;
if(ev_ind[0][0] >= it->dim_y)
{
err << "Requested row " << ev_ind[0][0] << " is out of bounds with dim_y=" << it->dim_y;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
if(ev_ind[1][0] >= it->dim_x)
{
err << "Requested column " << ev_ind[1][0] << " is out of bounds with dim_x=" << it->dim_x;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
res.value = {it->value.at(ev_ind[0][0]*it->dim_x + ev_ind[1][0])};//throw std::out_of_range
temp_attr_val << "[" <<res.value[0] << "],";//throw std::out_of_range
}
else if(ev_ind.size() == 2 && ev_ind[0].size() > 1 && ev_ind[1].size() == 1 && ev_ind[1][0] != -1)//single column slice of 2D array (e.g. [0,1,2][3])
{
res.dim_x = 1;
long ei1 = ev_ind[1][0];
if(ei1 >= it->dim_x)
{
err << "Requested column " << ei1 << " is out of bounds with dim_x=" << it->dim_x;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
for(auto ei0 : ev_ind[0])
{
if(ei0 < 0 || ei0 >= it->dim_y)
{
err << "Requested row " << ei0 << " is out of bounds with dim_y=" << it->dim_y;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
res.value.push_back(it->value.at(ei0*it->dim_x + ei1));//throw std::out_of_range
}
res.dim_y = ev_ind[0].size();
temp_attr_val <<print_array(res.value,res.dim_x,res.dim_y) <<",";
}
else if(ev_ind.size() == 2 && ev_ind[0].size() == 1 && ev_ind[0][0] == -1 && ev_ind[1].size() == 1 && ev_ind[1][0] != -1)//single column of 2D array (e.g. [-1][3])
{
res.dim_x = 1;
long ei1 = ev_ind[1][0];
if(ei1 >= it->dim_x)
{
err << "Requested column " << ei1 << " is out of bounds with dim_x=" << it->dim_x;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
for(long ei0 = 0; ei0 < it->dim_y; ei0++)
{
res.value.push_back(it->value.at(ei0*it->dim_x + ei1));//throw std::out_of_range
}
res.dim_y = it->dim_y;
temp_attr_val <<print_array(res.value,res.dim_x,res.dim_y) <<",";
}
else if(ev_ind.size() == 2 && ev_ind[0].size() == 1 && ev_ind[0][0] != -1 && ev_ind[1].size() > 1)//single row slice of 2D array (e.g. [0][1,2,3])
{
res.dim_y = 0;
long ei0 = ev_ind[0][0];
if(ei0 >= it->dim_y)
{
err << "Requested row " << ei0 << " is out of bounds with dim_y=" << it->dim_y;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
for(auto ei1 : ev_ind[1])
{
if(ei1 < 0 || ei1 >= it->dim_x)
{
err << "Requested column " << ei1 << " is out of bounds with dim_x=" << it->dim_x;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
res.value.push_back(it->value.at(ei0*it->dim_x + ei1));//throw std::out_of_range
}
res.dim_x = ev_ind[1].size();
temp_attr_val <<print_array(res.value,res.dim_x,res.dim_y) <<",";
}
else if(ev_ind.size() == 2 && ev_ind[0].size() > 1 && ev_ind[1].size() > 1)//subarray of 2D array (e.g. [0,1][2,3])
{
for(auto ei0 : ev_ind[0])
{
if(ei0 < 0 || ei0 >= it->dim_y)
{
err << "Requested row " << ei0 << " is out of bounds with dim_y=" << it->dim_y;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
for(auto ei1 : ev_ind[1])
{
if(ei1 < 0 || ei1 >= it->dim_x)
{
err << "Requested column " << ei1 << " is out of bounds with dim_x=" << it->dim_x;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
res.value.push_back(it->value.at(ei0*it->dim_x + ei1));//throw std::out_of_range
}
}
res.dim_x = ev_ind[1].size();
res.dim_y = ev_ind[0].size();
temp_attr_val <<print_array(res.value,res.dim_x,res.dim_y) <<",";
}
else if(ev_ind.size() == 2 && ev_ind[0].size() == 1 && ev_ind[0][0] == -1 && ev_ind[1].size() > 1)//subarray of 2D array (e.g. [-1][2,3])
{
for(long ei0 = 0; ei0 < it->dim_y; ei0++)
{
for(auto ei1 : ev_ind[1])
{
if(ei1 < 0 || ei1 >= it->dim_x)
{
err << "Requested column " << ei1 << " is out of bounds with dim_x=" << it->dim_x;
temp_attr_val << "[]";
events->veclock.readerOut();
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"OUT_OF_RANGE",
err.str(),
it->name);
}
res.value.push_back(it->value.at(ei0*it->dim_x + ei1));//throw std::out_of_range
}
}
res.dim_x = ev_ind[1].size();
res.dim_y = it->dim_y;
temp_attr_val <<print_array(res.value,res.dim_x,res.dim_y) <<",";
}
else //ev_ind.size() > 2
{
err << "UNSUPPORTED additional indexes in 2D array: " << ev_ind.size() << " indexes given, dim_x=" << it->dim_x << " dim_y=" << it->dim_y;
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
events->veclock.readerOut();
throw err.str();
}
}
else //TODO N-DIMENSIONAL arrays
{
err << "UNSUPPORTED array indexes: " << ev_ind.size() << " indexes given, dim_x=" << it->dim_x << " dim_y=" << it->dim_y;
DEBUG_STREAM << __func__ << ": " << err.str() << endl;
events->veclock.readerOut();
throw err.str();
}
}
else
{
res.value = it->value;
temp_attr_val << "\"" << it->name << "\":" <<print_array(res.value,res.dim_x,res.dim_y) << ",";
}
}
else
temp_attr_val << "\"" << it->name << "\":[],";
attr_values += temp_attr_val.str();
events->veclock.readerOut();
#ifdef _DEBUG_FORMULA #ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl; DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl;
#endif #endif
res.value = it->value.at(ev_ind); //throw std::out_of_range
events->veclock.readerOut();
return res; return res;
} }
else else
...@@ -4713,7 +5300,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4713,7 +5300,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
DEBUG_STREAM << " node index = " << val_d << endl; DEBUG_STREAM << " node index = " << val_d << endl;
#endif #endif
formula_res_t res; formula_res_t res;
res.value = strtod(val_d.c_str(), 0); res.valid = true;
res.value = {(strtod(val_d.c_str(), 0))};
res.dim_x=1;
res.dim_y=0;
return res; return res;
} }
else if (i->value.id() == formula_grammar::logical_exprID) else if (i->value.id() == formula_grammar::logical_exprID)
...@@ -4754,43 +5344,72 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4754,43 +5344,72 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
} }
formula_res_t res_1=eval_expression(i->children.begin(), attr_values), formula_res_t res_1=eval_expression(i->children.begin(), attr_values),
res_2=eval_expression(i->children.begin()+1, attr_values); res_2=eval_expression(i->children.begin()+1, attr_values);
long val_l1,val_l2; vector<long> val_l1(res_1.value.size()),val_l2(res_2.value.size());
bool valid = res_1.valid && res_2.valid;
string err2("ERROR: non-int value in bitwise operation!"); string err2("Non int value in bitwise operation");
val_l1 = (long)trunc(res_1.value); //transform to long std::transform(res_1.value.begin(), res_1.value.end(), val_l1.begin(),
val_l2 = (long)trunc(res_2.value); //transform to long [](double n) { return (long)trunc(n); });//transform to long
std::transform(res_2.value.begin(), res_2.value.end(), val_l2.begin(),
if((val_l1 != res_1.value) || (val_l2 != res_2.value)) //if different, lost something with truncf [](double n) { return (long)trunc(n); });//transform to long
throw err2; size_t ii;
for(ii=0; ii<res_1.value.size(); ii++)
{
if(val_l1[ii] != res_1.value[ii]) //if different, lost something with truncf
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"FORMULA_ERROR",
err2,
string("Bitwise ") + string(i->value.begin(), i->value.end()));
}
for(ii=0; ii<res_2.value.size(); ii++)
{
if(val_l2[ii] != res_2.value[ii]) //if different, lost something with truncf
Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"FORMULA_ERROR",
err2,
string("Bitwise ") + string(i->value.begin(), i->value.end()));
}
if (*i->value.begin() == '&') if (*i->value.begin() == '&')
{ {
formula_res_t res; formula_res_t res;
res.value = (double)(val_l1 & val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.valid = valid;
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y,val_l2,res_2.dim_x,res_2.dim_y,res.value,res.dim_x,res.dim_y, "Bitwise &", vectorUtils::fBitAnd);
return res; return res;
} }
else if (*i->value.begin() == '|') else if (*i->value.begin() == '|')
{ {
formula_res_t res; formula_res_t res;
res.value = (double)(val_l1 | val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.valid = valid;
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise |", vectorUtils::fBitOr);
return res; return res;
} }
else if (*i->value.begin() == '^') else if (*i->value.begin() == '^')
{ {
formula_res_t res; formula_res_t res;
res.value = (double)(val_l1 ^ val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.valid = valid;
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise ^", vectorUtils::fBitXor);
return res; return res;
} }
else else
...@@ -4811,33 +5430,59 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4811,33 +5430,59 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
} }
formula_res_t res_1=eval_expression(i->children.begin(), attr_values), formula_res_t res_1=eval_expression(i->children.begin(), attr_values),
res_2=eval_expression(i->children.begin()+1, attr_values); res_2=eval_expression(i->children.begin()+1, attr_values);
long val_l1,val_l2; vector<long> val_l1(res_1.value.size()),val_l2(res_2.value.size());
bool valid = res_1.valid && res_2.valid;
string err2("ERROR: non-int value in bitwise operation!"); string err2("Non int value in bitwise operation");
val_l1 = (long)trunc(res_1.value); //transform to long std::transform(res_1.value.begin(), res_1.value.end(), val_l1.begin(),
val_l2 = (long)trunc(res_2.value); //transform to long [](double n) { return (long)trunc(n); });//transform to long
std::transform(res_2.value.begin(), res_2.value.end(), val_l2.begin(),
if((val_l1 != res_1.value) || (val_l2 != res_2.value)) //if different, lost something with truncf [](double n) { return (long)trunc(n); });//transform to long
throw err2; bool non_int_error=false;
size_t ii;
for(ii=0; ii<res_1.value.size(); ii++)
{
if(val_l1[ii] != res_1.value[ii]) //if different, lost something with truncf
Tango::Except::throw_exception(//throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"FORMULA_ERROR",
err2,
string("Bitwise ") + string(i->value.begin(), i->value.end()));
}
for(ii=0; ii<res_2.value.size(); ii++)
{
if(val_l2[ii] != res_2.value[ii]) //if different, lost something with truncf
Tango::Except::throw_exception(//throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification)
(const char *)"FORMULA_ERROR",
err2,
string("Bitwise ") + string(i->value.begin(), i->value.end()));
}
if (string(i->value.begin(), i->value.end()) == string("<<")) if (string(i->value.begin(), i->value.end()) == string("<<"))
{ {
formula_res_t res; formula_res_t res;
res.value = (double)(val_l1 << val_l2); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.valid = valid;
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
vectorUtils::applyVectorFunc(val_l1, res_2.dim_x,res_2.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise <<", vectorUtils::fBitShiftL);
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string(">>")) else if (string(i->value.begin(), i->value.end()) == string(">>"))
{ {
formula_res_t res; formula_res_t res;
res.value = (double)(val_l1 >> val_l2);
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); res.valid = valid;
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); if(!res.valid)
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); {
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise >>", vectorUtils::fBitShiftR);
return res; return res;
} }
else else
...@@ -4883,20 +5528,45 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4883,20 +5528,45 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
err << "in node equality_exprID -> nameID(" << string(i2_1->value.begin(), i2_1->value.end()) << ") value not valid!"; err << "in node equality_exprID -> nameID(" << string(i2_1->value.begin(), i2_1->value.end()) << ") value not valid!";
if(it->ex_desc.length() > 0) if(it->ex_desc.length() > 0)
err << " EX: '" << it->ex_desc << "'"; err << " EX: '" << it->ex_desc << "'";
res.valid = false;
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.quality = it->quality;
res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc;
res.ex_origin = it->ex_origin;
events->veclock.readerOut(); events->veclock.readerOut();
throw err.str(); /*Tango::Except::throw_exception( //throw exception to have error not delayed
it->ex_reason,//or Event_ERROR
it->ex_desc,
it->ex_origin);*/
return res;
} }
else if(it->type != Tango::DEV_STRING && it->value.empty()) else if(it->type != Tango::DEV_STRING && it->value.empty())
{ {
err << "in node nameID(" << string(i2_1->value.begin(), i2_1->value.end()) << ") value not initialized!!"; err << "in node nameID(" << string(i2_1->value.begin(), i2_1->value.end()) << ") value not initialized!!";
if(it->ex_desc.length() > 0) if(it->ex_desc.length() > 0)
err << " EX: '" << it->ex_desc << "'"; err << " EX: '" << it->ex_desc << "'";
res.valid = false;
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.quality = it->quality;
res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc;
res.ex_origin = it->ex_origin;
events->veclock.readerOut(); events->veclock.readerOut();
throw err.str(); /*Tango::Except::throw_exception( //throw exception to have error not delayed
it->ex_reason,//or Event_ERROR
it->ex_desc,
it->ex_origin);*/
return res;
} }
ostringstream temp_attr_val; ostringstream temp_attr_val;
temp_attr_val << "\"" << it->name << "\":\"" <<it->value_string << "\","; temp_attr_val << "\"" << it->name << "\":\"" <<it->value_string << "\",";
attr_values += temp_attr_val.str(); attr_values += temp_attr_val.str();
res.valid = true;
res.dim_x = it->dim_x;
res.dim_y = it->dim_y;
res.quality = it->quality; res.quality = it->quality;
res.ex_reason = it->ex_reason; res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc; res.ex_desc = it->ex_desc;
...@@ -4919,12 +5589,16 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4919,12 +5589,16 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
if (string(i->value.begin(), i->value.end()) == string("!=")) if (string(i->value.begin(), i->value.end()) == string("!="))
{ {
res.value = attr_val != val_string; res.value = {(double)(attr_val != val_string)};
res.dim_x=1;
res.dim_y=0;
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string("==")) else if (string(i->value.begin(), i->value.end()) == string("=="))
{ {
res.value = attr_val == val_string; res.value = {(double)(attr_val == val_string)};
res.dim_x=1;
res.dim_y=0;
return res; return res;
} }
else else
...@@ -4985,7 +5659,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -4985,7 +5659,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
} }
else else
{ {
err << "in node equality_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed"; err << "in node compare_exprID(" << string(i->value.begin(), i->value.end()) << ") value not allowed";
throw err.str(); throw err.str();
} }
} }
...@@ -5004,109 +5678,49 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -5004,109 +5678,49 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
if (string(i->value.begin(), i->value.end()) == string("abs")) if (string(i->value.begin(), i->value.end()) == string("abs"))
{ {
res = eval_expression(i->children.begin(), attr_values); res = eval_expression(i->children.begin(), attr_values);
res.value = fabs(res.value); std::transform(res.value.begin(), res.value.end(), res.value.begin(),
[](double n) { return fabs(n); });
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string("cos")) else if (string(i->value.begin(), i->value.end()) == string("cos"))
{ {
res = eval_expression(i->children.begin(), attr_values); res = eval_expression(i->children.begin(), attr_values);
res.value = cos(res.value); std::transform(res.value.begin(), res.value.end(), res.value.begin(),
[](double n) { return cos(n); });
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string("sin")) else if (string(i->value.begin(), i->value.end()) == string("sin"))
{ {
res = eval_expression(i->children.begin(), attr_values); res = eval_expression(i->children.begin(), attr_values);
res.value = sin(res.value); std::transform(res.value.begin(), res.value.end(), res.value.begin(),
[](double n) { return sin(n); });
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string("quality")) else if (string(i->value.begin(), i->value.end()) == string("quality"))
{ {
res = eval_expression(i->children.begin(), attr_values); res = eval_expression(i->children.begin(), attr_values);
res.value = res.quality; res.value = {(double)res.quality};//ignore values and keep quality as result
res.dim_x=1;
res.dim_y=0;
return res; return res;
} }
else if ((string(i->value.begin(), i->value.end()) == string("AND") || string(i->value.begin(), i->value.end()) == string("OR")) && i->children.begin()->value.id() == formula_grammar::nameID) else if ((string(i->value.begin(), i->value.end()) == string("AND") || string(i->value.begin(), i->value.end()) == string("OR")))
{ {
events->veclock.readerIn(); res = eval_expression(i->children.begin(), attr_values);
vector<event>::iterator it = events->v_event.begin(); res.dim_x=1;
string s(i->children.begin()->value.begin(), i->children.begin()->value.end()); res.dim_y=0;
std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase if(string(i->value.begin(), i->value.end()) == string("AND"))
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << " -> " << string(i->value.begin(), i->value.end()) << "(" << s << ")" << endl;
#endif
while ((it != events->v_event.end()) && (it->name != s))
it++;
if (it != events->v_event.end())
{ {
if(!it->valid) res.value = {(double)std::accumulate(res.value.begin(), res.value.end(), (bool)true, [](bool acc, double n) { return (bool)(acc && (bool)(n));})};
{
err << "in node funcID(" << string(i->value.begin(), i->value.end()) << "), (" << s << ") value not valid!" << ends;
if(it->ex_desc.length() > 0)
err << it->ex_desc << "";
else
err << "attribute " << string(i->value.begin(), i->value.end()) << " value not valid while evaluating formula";
events->veclock.readerOut();
throw err.str();
}
else if(it->type != Tango::DEV_STRING && it->value.empty())
{
if(it->ex_desc.length() > 0)
err << it->ex_desc << "";
else
err << "attribute " << string(i->value.begin(), i->value.end()) << " value not initialized while evaluating formula";
events->veclock.readerOut();
throw err.str();
}
ostringstream temp_attr_val;
bool result;
if (string(i->value.begin(), i->value.end()) == string("AND"))
result = true;
else if (string(i->value.begin(), i->value.end()) == string("OR"))
result = false;
temp_attr_val << "\"" << it->name << "\":";
if(it->read_size > 1)
temp_attr_val << "[";
for(int att_ind = 0; att_ind < it->read_size && att_ind < it->value.size(); att_ind++)
{
temp_attr_val << it->value.at(att_ind);
if (string(i->value.begin(), i->value.end()) == string("AND"))
{
result = result && (bool)it->value.at(att_ind);
if(!result) //comment to have all array values in attr_values
break; //comment to have all array values in attr_values
}
else if (string(i->value.begin(), i->value.end()) == string("OR"))
{
result = result || (bool)it->value.at(att_ind);
if(result) //comment to have all array values in attr_values
break; //comment to have all array values in attr_values
}
if(att_ind < it->read_size-1 && att_ind < it->value.size()-1)
temp_attr_val << ",";
}
if(it->read_size > 1)
temp_attr_val << "]";
temp_attr_val << ",";
attr_values += temp_attr_val.str();
res.quality = it->quality;
res.ex_reason = it->ex_reason;
res.ex_desc = it->ex_desc;
res.ex_origin = it->ex_origin;
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl;
#endif
res.value = result;
events->veclock.readerOut();
return res;
} }
else else if(string(i->value.begin(), i->value.end()) == string("OR"))
{ {
events->veclock.readerOut(); res.value = {(double)std::accumulate(res.value.begin(), res.value.end(), (bool)false, [](bool acc, double n) { return (bool)(acc || (bool)(n));})};
err << "in function " << string(i->value.begin(), i->value.end()) << " event (" << s << ") not found in event table" << ends;
throw err.str();
} }
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node funcID("<<string(i->value.begin(), i->value.end())<<") value="<<print_array(res.value,res.dim_x,res.dim_y)<<" quality="<<res.quality<< endl;
#endif
return res;
} }
else else
{ {
...@@ -5126,34 +5740,47 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -5126,34 +5740,47 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
} }
formula_res_t res_1=eval_expression(i->children.begin(), attr_values), formula_res_t res_1=eval_expression(i->children.begin(), attr_values),
res_2=eval_expression(i->children.begin()+1, attr_values); res_2=eval_expression(i->children.begin()+1, attr_values);
bool valid = res_1.valid && res_2.valid;
if (string(i->value.begin(), i->value.end()) == string("min")) if (string(i->value.begin(), i->value.end()) == string("min"))
{ {
formula_res_t res; formula_res_t res;
res.value = min(res_1.value, res_2.value); vectorUtils::applyVectorFunc(res_1.value, res_1.dim_x,res_1.dim_y, res_2.value, res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, string(i->value.begin(), i->value.end()), vectorUtils::fMin);
res.valid = valid;
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string("max")) else if (string(i->value.begin(), i->value.end()) == string("max"))
{ {
formula_res_t res; formula_res_t res;
res.value = max(res_1.value, res_2.value); vectorUtils::applyVectorFunc(res_1.value, res_1.dim_x,res_1.dim_y, res_2.value, res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, string(i->value.begin(), i->value.end()), vectorUtils::fMax);
res.valid = valid;
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
return res; return res;
} }
else if (string(i->value.begin(), i->value.end()) == string("pow")) else if (string(i->value.begin(), i->value.end()) == string("pow"))
{ {
formula_res_t res; formula_res_t res;
res.value = pow(res_1.value, res_2.value); vectorUtils::applyVectorFunc(res_1.value, res_1.dim_x,res_1.dim_y, res_2.value, res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, string(i->value.begin(), i->value.end()), vectorUtils::fPow);
res.valid = valid;
res.quality = res.combine_quality(res_1.quality, res_2.quality); res.quality = res.combine_quality(res_1.quality, res_2.quality);
res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason); if(!res.valid)
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); {
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); res.ex_reason = res.combine_exception(res_1.ex_reason, res_2.ex_reason);
res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc);
res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin);
}
return res; return res;
} }
else else
...@@ -5173,7 +5800,15 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -5173,7 +5800,15 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
throw err.str(); throw err.str();
} }
formula_res_t res_1=eval_expression(i->children.begin(), attr_values); formula_res_t res_1=eval_expression(i->children.begin(), attr_values);
if(res_1.value) if(!res_1.valid || res_1.value.empty())
{
#ifdef _DEBUG_FORMULA
DEBUG_STREAM << " node ternary_if expression: returning Error=" << res_1.ex_desc << endl;
#endif
return res_1;
}
res_1.extract_result();
if(res_1.value[0])
{ {
formula_res_t res = eval_expression(i->children.begin()+1, attr_values); formula_res_t res = eval_expression(i->children.begin()+1, attr_values);
return res; return res;
...@@ -5195,7 +5830,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values ...@@ -5195,7 +5830,10 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values
} }
} }
formula_res_t res; formula_res_t res;
res.value = 0; res.value = {(double)0.0};
res.dim_x=1;
res.dim_y=0;
res.valid = false;
return res; return res;
} }
...@@ -5228,7 +5866,7 @@ void AlarmHandler::eval_node_event(iter_t const& i, vector<string> & ev) ...@@ -5228,7 +5866,7 @@ void AlarmHandler::eval_node_event(iter_t const& i, vector<string> & ev)
std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase std::transform(s.begin(), s.end(), s.begin(), (int(*)(int))tolower); //transform to lowercase
ev.push_back(s); ev.push_back(s);
} }
//cout << endl; //TANGO_LOG << endl;
//iter_t it = i->children.begin(); //iter_t it = i->children.begin();
for(iter_t it = i->children.begin(); it != i->children.end(); it++) for(iter_t it = i->children.begin(); it != i->children.end(); it++)
eval_node_event(it, ev); eval_node_event(it, ev);
...@@ -5287,7 +5925,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5287,7 +5925,7 @@ void AlarmHandler::prepare_alarm_attr()
} }
else else
{ {
if(ai->second.stat == S_ALARM && ai->second.ack == ACK) if(ai->second.stat == S_ALARM && ai->second.ack == ACK && !ai->second.error)
{ {
acknowledgedAlarms_read[acknowledgedAlarms_sz] = ai->second.name; acknowledgedAlarms_read[acknowledgedAlarms_sz] = ai->second.name;
attr_alarmAcknowledged_read[acknowledgedAlarms_sz] = const_cast<char*>(acknowledgedAlarms_read[acknowledgedAlarms_sz].c_str()); attr_alarmAcknowledged_read[acknowledgedAlarms_sz] = const_cast<char*>(acknowledgedAlarms_read[acknowledgedAlarms_sz].c_str());
...@@ -5297,7 +5935,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5297,7 +5935,7 @@ void AlarmHandler::prepare_alarm_attr()
acknowledgedAlarms_sz++; acknowledgedAlarms_sz++;
almstate = "ACKED"; almstate = "ACKED";
} }
else if(ai->second.stat == S_ALARM && ai->second.ack == NOT_ACK) else if(ai->second.stat == S_ALARM && ai->second.ack == NOT_ACK && !ai->second.error)
{ {
unacknowledgedAlarms_read[unacknowledgedAlarms_sz] = ai->second.name; unacknowledgedAlarms_read[unacknowledgedAlarms_sz] = ai->second.name;
attr_alarmUnacknowledged_read[unacknowledgedAlarms_sz] = const_cast<char*>(unacknowledgedAlarms_read[unacknowledgedAlarms_sz].c_str()); attr_alarmUnacknowledged_read[unacknowledgedAlarms_sz] = const_cast<char*>(unacknowledgedAlarms_read[unacknowledgedAlarms_sz].c_str());
...@@ -5307,7 +5945,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5307,7 +5945,7 @@ void AlarmHandler::prepare_alarm_attr()
unacknowledgedAlarms_sz++; unacknowledgedAlarms_sz++;
almstate = "UNACK"; almstate = "UNACK";
} }
else if(ai->second.stat == S_NORMAL && ai->second.ack == NOT_ACK) else if(ai->second.stat == S_NORMAL && ai->second.ack == NOT_ACK && !ai->second.error)
{ {
unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz] = ai->second.name; unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz] = ai->second.name;
attr_alarmUnacknowledgedNormal_read[unacknowledgedNormalAlarms_sz] = const_cast<char*>(unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz].c_str()); attr_alarmUnacknowledgedNormal_read[unacknowledgedNormalAlarms_sz] = const_cast<char*>(unacknowledgedNormalAlarms_read[unacknowledgedNormalAlarms_sz].c_str());
...@@ -5317,7 +5955,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5317,7 +5955,7 @@ void AlarmHandler::prepare_alarm_attr()
unacknowledgedNormalAlarms_sz++; unacknowledgedNormalAlarms_sz++;
almstate = "RTNUN"; almstate = "RTNUN";
} }
else if(ai->second.stat == S_NORMAL && ai->second.ack == ACK) else if(ai->second.stat == S_NORMAL && ai->second.ack == ACK && !ai->second.error)
{ {
normalAlarms_read[normalAlarms_sz] = ai->second.name; normalAlarms_read[normalAlarms_sz] = ai->second.name;
attr_alarmNormal_read[normalAlarms_sz] = const_cast<char*>(normalAlarms_read[normalAlarms_sz].c_str()); attr_alarmNormal_read[normalAlarms_sz] = const_cast<char*>(normalAlarms_read[normalAlarms_sz].c_str());
...@@ -5347,7 +5985,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5347,7 +5985,7 @@ void AlarmHandler::prepare_alarm_attr()
if(almstate == "OOSRV" || almstate == "SHLVD") if(almstate == "OOSRV" || almstate == "SHLVD")
{ {
//cout << __func__ << ": " << ai->first << " silenced="<< ai->second.silenced << endl; //TANGO_LOG << __func__ << ": " << ai->first << " silenced="<< ai->second.silenced << endl;
#if 0 #if 0
alm_disabled << KEY(ALARM_TIME_KEY) << time_buf << "." << ai->second.ts.tv_usec << SEP; alm_disabled << KEY(ALARM_TIME_KEY) << time_buf << "." << ai->second.ts.tv_usec << SEP;
alm_disabled << KEY(NAME_KEY) << ai->first << SEP; alm_disabled << KEY(NAME_KEY) << ai->first << SEP;
...@@ -5385,7 +6023,6 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5385,7 +6023,6 @@ void AlarmHandler::prepare_alarm_attr()
time_sec= ai->second.ts.tv_sec; time_sec= ai->second.ts.tv_sec;
//gmtime_r(&time_sec,&time_tm); //-> UTC //gmtime_r(&time_sec,&time_tm); //-> UTC
localtime_r(&time_sec,&time_tm); localtime_r(&time_sec,&time_tm);
time_buf[64];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm); strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &time_tm);
#ifndef ALM_SUM_STR #ifndef ALM_SUM_STR
...@@ -5483,7 +6120,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5483,7 +6120,7 @@ void AlarmHandler::prepare_alarm_attr()
* found, change stat only if switching from * found, change stat only if switching from
* S_NORMAL or S_ALARM status to S_ERROR * S_NORMAL or S_ALARM status to S_ERROR
*/ */
//cout << "read_attr(): S_ERROR: found: " << aid->name << endl; //TANGO_LOG << "read_attr(): S_ERROR: found: " << aid->name << endl;
if (aid->stat != S_ERROR) { if (aid->stat != S_ERROR) {
aid->stat = S_ERROR; aid->stat = S_ERROR;
aid->ack = NOT_ACK; aid->ack = NOT_ACK;
...@@ -5494,6 +6131,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5494,6 +6131,7 @@ void AlarmHandler::prepare_alarm_attr()
aid->grp = ai->second.grp; aid->grp = ai->second.grp;
aid->lev = ai->second.lev; aid->lev = ai->second.lev;
aid->is_new = ai->second.is_new; //copy is_new state aid->is_new = ai->second.is_new; //copy is_new state
aid->receivers = ai->second.receivers;
//ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0 //ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0
#ifdef _CNT_ATOMIC #ifdef _CNT_ATOMIC
aid->on_counter.store(ai->second.on_counter); aid->on_counter.store(ai->second.on_counter);
...@@ -5533,7 +6171,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5533,7 +6171,7 @@ void AlarmHandler::prepare_alarm_attr()
* found, change stat only if switching from * found, change stat only if switching from
* S_NORMAL to S_ALARM status * S_NORMAL to S_ALARM status
*/ */
//cout << "read_attr(): S_ALARM: found: " << aid->name << endl; //TANGO_LOG << "read_attr(): S_ALARM: found: " << aid->name << endl;
if (aid->stat == S_NORMAL || aid->stat == S_ERROR) { if (aid->stat == S_NORMAL || aid->stat == S_ERROR) {
aid->stat = S_ALARM; aid->stat = S_ALARM;
aid->ack = NOT_ACK; aid->ack = NOT_ACK;
...@@ -5544,6 +6182,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5544,6 +6182,7 @@ void AlarmHandler::prepare_alarm_attr()
aid->grp = ai->second.grp; aid->grp = ai->second.grp;
aid->lev = ai->second.lev; aid->lev = ai->second.lev;
aid->is_new = ai->second.is_new; //copy is_new state aid->is_new = ai->second.is_new; //copy is_new state
aid->receivers = ai->second.receivers;
//ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0 //ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0
#ifdef _CNT_ATOMIC #ifdef _CNT_ATOMIC
aid->on_counter.store(ai->second.on_counter); aid->on_counter.store(ai->second.on_counter);
...@@ -5598,6 +6237,7 @@ void AlarmHandler::prepare_alarm_attr() ...@@ -5598,6 +6237,7 @@ void AlarmHandler::prepare_alarm_attr()
aid->is_new = ai->second.is_new; //copy is_new state aid->is_new = ai->second.is_new; //copy is_new state
aid->silenced = ai->second.silenced; //update silenced from alarm table (maybe not necessary) aid->silenced = ai->second.silenced; //update silenced from alarm table (maybe not necessary)
aid->silent_time = ai->second.silent_time; //if already alarmed and not saved correctly in properties needed to update aid->silent_time = ai->second.silent_time; //if already alarmed and not saved correctly in properties needed to update
aid->receivers = ai->second.receivers;
//ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0 //ai->second.is_new = 0; //and set state as not more new //12-06-08: StopNew command set it to 0
if (aid->ack == ACK) { if (aid->ack == ACK) {
//if (aid->done) //TODO: done seems useless //if (aid->done) //TODO: done seems useless
...@@ -5800,7 +6440,7 @@ void AlarmHandler::put_signal_property() ...@@ -5800,7 +6440,7 @@ void AlarmHandler::put_signal_property()
DECLARE_TIME_VAR t0, t1; DECLARE_TIME_VAR t0, t1;
GET_TIME(t0); GET_TIME(t0);
alarms.save_alarm_conf_db(it.second.attr_name,it.second.name,it.second.stat,it.second.ack,it.second.enabled, alarms.save_alarm_conf_db(it.second.attr_name,it.second.name,it.second.stat,it.second.ack,it.second.enabled,
it.second.formula,it.second.on_delay,it.second.off_delay,it.second.grp2str(),it.second.lev,it.second.msg,it.second.url,it.second.cmd_name_a,it.second.cmd_name_n,it.second.silent_time); it.second.formula,it.second.on_delay,it.second.off_delay,it.second.grp2str(),it.second.lev,it.second.msg,it.second.url,it.second.cmd_name_a,it.second.cmd_name_n,it.second.receivers,it.second.silent_time);
GET_TIME(t1); GET_TIME(t1);
DEBUG_STREAM << __func__ << ": SAVED '" <<it.first << "' in " << ELAPSED(t0, t1) << " ms" << endl; DEBUG_STREAM << __func__ << ": SAVED '" <<it.first << "' in " << ELAPSED(t0, t1) << " ms" << endl;
//alarms.vlock->readerOut();//TODO: avoid keeping lock //alarms.vlock->readerOut();//TODO: avoid keeping lock
...@@ -5823,7 +6463,7 @@ void AlarmHandler::put_signal_property() ...@@ -5823,7 +6463,7 @@ void AlarmHandler::put_signal_property()
itmap->second = conf_string; itmap->second = conf_string;
savedlock->readerOut(); savedlock->readerOut();
alarms.save_alarm_conf_db(it.second.attr_name,it.second.name,it.second.stat,it.second.ack,it.second.enabled, alarms.save_alarm_conf_db(it.second.attr_name,it.second.name,it.second.stat,it.second.ack,it.second.enabled,
it.second.formula,it.second.on_delay,it.second.off_delay,it.second.grp2str(),it.second.lev,it.second.msg,it.second.url,it.second.cmd_name_a,it.second.cmd_name_n,it.second.silent_time); it.second.formula,it.second.on_delay,it.second.off_delay,it.second.grp2str(),it.second.lev,it.second.msg,it.second.url,it.second.cmd_name_a,it.second.cmd_name_n,it.second.receivers,it.second.silent_time);
GET_TIME(t1); GET_TIME(t1);
DEBUG_STREAM << __func__ << ": UPDATED '" <<it.first << "' in " << ELAPSED(t0, t1) << " ms" << endl; DEBUG_STREAM << __func__ << ": UPDATED '" <<it.first << "' in " << ELAPSED(t0, t1) << " ms" << endl;
} }
...@@ -5834,8 +6474,13 @@ void AlarmHandler::put_signal_property() ...@@ -5834,8 +6474,13 @@ void AlarmHandler::put_signal_property()
} }
} }
// Identify the alarms that need to be removed.
// The alarms that have been identified to be removed have their tag
// stored in a std::vector. The vector is later iterated over in a second
// step when the alarms get removed.
savedlock->readerIn(); savedlock->readerIn();
map<string, string>::iterator it2=saved_alarms.begin(); map<string, string>::iterator it2=saved_alarms.begin();
vector< string > alarms_to_be_erased;
while(it2 != saved_alarms.end()) while(it2 != saved_alarms.end())
{ {
if(!it2->first.empty())//TODO: should not be needed, bug if it happens if(!it2->first.empty())//TODO: should not be needed, bug if it happens
...@@ -5843,25 +6488,30 @@ void AlarmHandler::put_signal_property() ...@@ -5843,25 +6488,30 @@ void AlarmHandler::put_signal_property()
auto found = local_alarms.find(it2->first); auto found = local_alarms.find(it2->first);
if (found == local_alarms.end()) if (found == local_alarms.end())
{ {
DEBUG_STREAM << __func__<<": DELETING '" << it2->first << "'" << endl; alarms_to_be_erased.push_back(it2->first);
DECLARE_TIME_VAR t0, t1;
GET_TIME(t0);
alarms.delete_alarm_conf_db(it2->first);
GET_TIME(t1);
DEBUG_STREAM << __func__ << ": DELETED '" <<it2->first << "' in " << ELAPSED(t0, t1) << " ms" << endl;
//savedlock->readerOut();//TODO: with boost shared lock to be released to take exclusive
savedlock->writerIn();
saved_alarms.erase(it2);
savedlock->writerOut();
//savedlock->readerIn();
} }
} }
if(it2 != saved_alarms.end()) if(it2 != saved_alarms.end())
it2++; it2++;
} }
savedlock->readerOut(); savedlock->readerOut();
// Now remove the alarms from the property in the TangoDB and saved_alarms.
if(!alarms_to_be_erased.empty())
{
savedlock->writerIn();
for(auto iter{alarms_to_be_erased.begin()}; iter != alarms_to_be_erased.end(); ++iter)
{
DEBUG_STREAM << __func__<<": DELETING '" << *iter << "' saved_alarms.size=" << saved_alarms.size() << endl;
DECLARE_TIME_VAR t0, t1;
GET_TIME(t0);
alarms.delete_alarm_conf_db(*iter);
GET_TIME(t1);
DEBUG_STREAM << __func__ << ": DELETED '" << *iter << "' in " << ELAPSED(t0, t1) << " ms saved_alarms.size=" << saved_alarms.size() << endl;
saved_alarms.erase(saved_alarms.find(*iter));
}
savedlock->writerOut();
}
Tango::DbData data; Tango::DbData data;
data.push_back(Tango::DbDatum("AlarmList")); data.push_back(Tango::DbDatum("AlarmList"));
...@@ -5972,6 +6622,7 @@ void AlarmHandler::parse_alarm(string &alarm_string, alarm_t &alm) ...@@ -5972,6 +6622,7 @@ void AlarmHandler::parse_alarm(string &alarm_string, alarm_t &alm)
alm.dp_n = NULL; alm.dp_n = NULL;
alm.enabled=true; alm.enabled=true;
alm.shelved=false; alm.shelved=false;
alm.receivers.clear();
alm.formula_tree = alm.formula_tree =
//boost::spirit::tree_parse_info< std::string::iterator, factory_t> tmp = //boost::spirit::tree_parse_info< std::string::iterator, factory_t> tmp =
...@@ -5995,6 +6646,7 @@ void AlarmHandler::parse_alarm(string &alarm_string, alarm_t &alm) ...@@ -5995,6 +6646,7 @@ void AlarmHandler::parse_alarm(string &alarm_string, alarm_t &alm)
std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase std::transform(alm.lev.begin(), alm.lev.end(), alm.lev.begin(), (int(*)(int))tolower); //transform to lowercase
alm.msg = std::regex_replace(alm.msg, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";" alm.msg = std::regex_replace(alm.msg, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
alm.url = std::regex_replace(alm.url, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";" alm.url = std::regex_replace(alm.url, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
alm.receivers = std::regex_replace(alm.receivers, std::regex(R"((\\;)|(;;))"), ";"); //match raw string "\;" or ";;" and replace with ";"
if(alm.cmd_name_a.length() > 0) if(alm.cmd_name_a.length() > 0)
{ {
const char *c = alm.cmd_name_a.c_str(); const char *c = alm.cmd_name_a.c_str();
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#ifndef AlarmHandler_H #ifndef AlarmHandler_H
#define AlarmHandler_H #define AlarmHandler_H
#include <tango.h> #include <tango/tango.h>
#include <boost/version.hpp> #include <boost/version.hpp>
#if BOOST_VERSION >= 103600 #if BOOST_VERSION >= 103600
...@@ -61,7 +61,15 @@ class update_thread; ...@@ -61,7 +61,15 @@ class update_thread;
# define ELAPSED(before, after) \ # define ELAPSED(before, after) \
1000.0*(after.tv_sec-before.tv_sec) + \ 1000.0*(after.tv_sec-before.tv_sec) + \
((double)after.tv_usec-before.tv_usec) / 1000 ((double)after.tv_usec-before.tv_usec) / 1000
#ifndef TANGO_LOG
#define TANGO_LOG cout
#endif
#ifndef TANGO_LOG_INFO
#define TANGO_LOG_INFO cout2
#endif
#ifndef TANGO_LOG_DEBUG
#define TANGO_LOG_DEBUG cout4
#endif
/*----- PROTECTED REGION END -----*/ // AlarmHandler.h /*----- PROTECTED REGION END -----*/ // AlarmHandler.h
...@@ -585,13 +593,13 @@ private: ...@@ -585,13 +593,13 @@ private:
void init_alarms(map< string,vector<string> > &alarm_events); void init_alarms(map< string,vector<string> > &alarm_events);
#endif #endif
void add_alarm(alarm_t& a, bool starting=false); void add_alarm(alarm_t& a, bool starting=false);
void add_event(alarm_t& a, vector<string> &evn) throw(string&); void add_event(alarm_t& a, vector<string> &evn);
#if 0 #if 0
void subscribe_event(alarm_t& a, EventCallBack& ecb, vector<string> &evn) throw(string&); void subscribe_event(alarm_t& a, EventCallBack& ecb, vector<string> &evn);
#endif #endif
// void do_alarm(bei_t& e); //gcc 4 problem?? // void do_alarm(bei_t& e); //gcc 4 problem??
bool remove_alarm(string& s) throw(string&); bool remove_alarm(string& s);
//void add_to_database(alarm_t& a) throw(string&); //void add_to_database(alarm_t& a);
void set_internal_alarm(string name, Tango::TimeVal t, string msg, unsigned int count=1); void set_internal_alarm(string name, Tango::TimeVal t, string msg, unsigned int count=1);
void load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn); void load_alarm(string alarm_string, alarm_t &alm, vector<string> &evn);
...@@ -599,7 +607,8 @@ private: ...@@ -599,7 +607,8 @@ private:
formula_res_t eval_formula(tree_parse_info_t tree, string &attr_values); formula_res_t eval_formula(tree_parse_info_t tree, string &attr_values);
void find_event_formula(tree_parse_info_t tree, vector<string> &); void find_event_formula(tree_parse_info_t tree, vector<string> &);
formula_res_t eval_expression(iter_t const& i, string &attr_values, int ev_ind=0); //recursive tree node evaluation formula_res_t eval_expression(iter_t const& i, string &attr_values, vector< vector<double> > ev_ind={}); //recursive tree node evaluation
void eval_index_range(iter_t const& i, string &attr_values, vector<double> & ind);
void eval_node_event(iter_t const& i, vector<string> & ev); //recursive tree node evaluation void eval_node_event(iter_t const& i, vector<string> & ev); //recursive tree node evaluation
void prepare_alarm_attr(); //for read attribute alarm and push_change_event void prepare_alarm_attr(); //for read attribute alarm and push_change_event
......
/*----- PROTECTED REGION ID(AlarmHandlerClass.cpp) ENABLED START -----*/ /*----- PROTECTED REGION ID(AlarmHandlerClass.cpp) ENABLED START -----*/
static const char *RcsId = "$Id: $";
static const char *TagName = "$Name: $";
static const char *CvsPath = "$Source: $";
static const char *SvnPath = "$HeadURL: $";
static const char *HttpServer = "http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/";
//============================================================================= //=============================================================================
// //
// file : AlarmHandlerClass.cpp // file : AlarmHandlerClass.cpp
...@@ -78,7 +73,7 @@ AlarmHandlerClass *AlarmHandlerClass::_instance = NULL; ...@@ -78,7 +73,7 @@ AlarmHandlerClass *AlarmHandlerClass::_instance = NULL;
//-------------------------------------------------------- //--------------------------------------------------------
AlarmHandlerClass::AlarmHandlerClass(string &s):Tango::DeviceClass(s) AlarmHandlerClass::AlarmHandlerClass(string &s):Tango::DeviceClass(s)
{ {
cout2 << "Entering AlarmHandlerClass constructor" << endl; TANGO_LOG_INFO << "Entering AlarmHandlerClass constructor" << endl;
set_default_property(); set_default_property();
get_class_property(); get_class_property();
write_class_property(); write_class_property();
...@@ -87,7 +82,7 @@ AlarmHandlerClass::AlarmHandlerClass(string &s):Tango::DeviceClass(s) ...@@ -87,7 +82,7 @@ AlarmHandlerClass::AlarmHandlerClass(string &s):Tango::DeviceClass(s)
/*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::constructor /*----- PROTECTED REGION END -----*/ // AlarmHandlerClass::constructor
cout2 << "Leaving AlarmHandlerClass constructor" << endl; TANGO_LOG_INFO << "Leaving AlarmHandlerClass constructor" << endl;
} }
//-------------------------------------------------------- //--------------------------------------------------------
...@@ -167,7 +162,7 @@ AlarmHandlerClass *AlarmHandlerClass::instance() ...@@ -167,7 +162,7 @@ AlarmHandlerClass *AlarmHandlerClass::instance()
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *AckClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *AckClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "AckClass::execute(): arrived" << endl; TANGO_LOG_INFO << "AckClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin; const Tango::DevVarStringArray *argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->ack(argin)); ((static_cast<AlarmHandler *>(device))->ack(argin));
...@@ -187,7 +182,7 @@ CORBA::Any *AckClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_an ...@@ -187,7 +182,7 @@ CORBA::Any *AckClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_an
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *LoadClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *LoadClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "LoadClass::execute(): arrived" << endl; TANGO_LOG_INFO << "LoadClass::execute(): arrived" << endl;
Tango::DevString argin; Tango::DevString argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->load(argin)); ((static_cast<AlarmHandler *>(device))->load(argin));
...@@ -207,7 +202,7 @@ CORBA::Any *LoadClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_a ...@@ -207,7 +202,7 @@ CORBA::Any *LoadClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_a
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *RemoveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *RemoveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "RemoveClass::execute(): arrived" << endl; TANGO_LOG_INFO << "RemoveClass::execute(): arrived" << endl;
Tango::DevString argin; Tango::DevString argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->remove(argin)); ((static_cast<AlarmHandler *>(device))->remove(argin));
...@@ -227,7 +222,7 @@ CORBA::Any *RemoveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in ...@@ -227,7 +222,7 @@ CORBA::Any *RemoveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *SearchAlarmClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *SearchAlarmClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "SearchAlarmClass::execute(): arrived" << endl; TANGO_LOG_INFO << "SearchAlarmClass::execute(): arrived" << endl;
Tango::DevString argin; Tango::DevString argin;
extract(in_any, argin); extract(in_any, argin);
return insert((static_cast<AlarmHandler *>(device))->search_alarm(argin)); return insert((static_cast<AlarmHandler *>(device))->search_alarm(argin));
...@@ -246,7 +241,7 @@ CORBA::Any *SearchAlarmClass::execute(Tango::DeviceImpl *device, const CORBA::An ...@@ -246,7 +241,7 @@ CORBA::Any *SearchAlarmClass::execute(Tango::DeviceImpl *device, const CORBA::An
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *StopAudibleClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) CORBA::Any *StopAudibleClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{ {
cout2 << "StopAudibleClass::execute(): arrived" << endl; TANGO_LOG_INFO << "StopAudibleClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->stop_audible()); ((static_cast<AlarmHandler *>(device))->stop_audible());
return new CORBA::Any(); return new CORBA::Any();
} }
...@@ -264,7 +259,7 @@ CORBA::Any *StopAudibleClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(co ...@@ -264,7 +259,7 @@ CORBA::Any *StopAudibleClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(co
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *SilenceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *SilenceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "SilenceClass::execute(): arrived" << endl; TANGO_LOG_INFO << "SilenceClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin; const Tango::DevVarStringArray *argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->silence(argin)); ((static_cast<AlarmHandler *>(device))->silence(argin));
...@@ -284,7 +279,7 @@ CORBA::Any *SilenceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &i ...@@ -284,7 +279,7 @@ CORBA::Any *SilenceClass::execute(Tango::DeviceImpl *device, const CORBA::Any &i
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *ModifyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *ModifyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "ModifyClass::execute(): arrived" << endl; TANGO_LOG_INFO << "ModifyClass::execute(): arrived" << endl;
Tango::DevString argin; Tango::DevString argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->modify(argin)); ((static_cast<AlarmHandler *>(device))->modify(argin));
...@@ -304,7 +299,7 @@ CORBA::Any *ModifyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in ...@@ -304,7 +299,7 @@ CORBA::Any *ModifyClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *ShelveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *ShelveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "ShelveClass::execute(): arrived" << endl; TANGO_LOG_INFO << "ShelveClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin; const Tango::DevVarStringArray *argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->shelve(argin)); ((static_cast<AlarmHandler *>(device))->shelve(argin));
...@@ -324,7 +319,7 @@ CORBA::Any *ShelveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in ...@@ -324,7 +319,7 @@ CORBA::Any *ShelveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *EnableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *EnableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "EnableClass::execute(): arrived" << endl; TANGO_LOG_INFO << "EnableClass::execute(): arrived" << endl;
Tango::DevString argin; Tango::DevString argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->enable(argin)); ((static_cast<AlarmHandler *>(device))->enable(argin));
...@@ -344,7 +339,7 @@ CORBA::Any *EnableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in ...@@ -344,7 +339,7 @@ CORBA::Any *EnableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *DisableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *DisableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "DisableClass::execute(): arrived" << endl; TANGO_LOG_INFO << "DisableClass::execute(): arrived" << endl;
Tango::DevString argin; Tango::DevString argin;
extract(in_any, argin); extract(in_any, argin);
((static_cast<AlarmHandler *>(device))->disable(argin)); ((static_cast<AlarmHandler *>(device))->disable(argin));
...@@ -364,7 +359,7 @@ CORBA::Any *DisableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &i ...@@ -364,7 +359,7 @@ CORBA::Any *DisableClass::execute(Tango::DeviceImpl *device, const CORBA::Any &i
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *ResetStatisticsClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) CORBA::Any *ResetStatisticsClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{ {
cout2 << "ResetStatisticsClass::execute(): arrived" << endl; TANGO_LOG_INFO << "ResetStatisticsClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->reset_statistics()); ((static_cast<AlarmHandler *>(device))->reset_statistics());
return new CORBA::Any(); return new CORBA::Any();
} }
...@@ -382,7 +377,7 @@ CORBA::Any *ResetStatisticsClass::execute(Tango::DeviceImpl *device, TANGO_UNUSE ...@@ -382,7 +377,7 @@ CORBA::Any *ResetStatisticsClass::execute(Tango::DeviceImpl *device, TANGO_UNUSE
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *StopNewClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) CORBA::Any *StopNewClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{ {
cout2 << "StopNewClass::execute(): arrived" << endl; TANGO_LOG_INFO << "StopNewClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->stop_new()); ((static_cast<AlarmHandler *>(device))->stop_new());
return new CORBA::Any(); return new CORBA::Any();
} }
...@@ -400,7 +395,7 @@ CORBA::Any *StopNewClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const ...@@ -400,7 +395,7 @@ CORBA::Any *StopNewClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *GetAlarmInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) CORBA::Any *GetAlarmInfoClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any)
{ {
cout2 << "GetAlarmInfoClass::execute(): arrived" << endl; TANGO_LOG_INFO << "GetAlarmInfoClass::execute(): arrived" << endl;
const Tango::DevVarStringArray *argin; const Tango::DevVarStringArray *argin;
extract(in_any, argin); extract(in_any, argin);
return insert((static_cast<AlarmHandler *>(device))->get_alarm_info(argin)); return insert((static_cast<AlarmHandler *>(device))->get_alarm_info(argin));
...@@ -419,7 +414,7 @@ CORBA::Any *GetAlarmInfoClass::execute(Tango::DeviceImpl *device, const CORBA::A ...@@ -419,7 +414,7 @@ CORBA::Any *GetAlarmInfoClass::execute(Tango::DeviceImpl *device, const CORBA::A
//-------------------------------------------------------- //--------------------------------------------------------
CORBA::Any *ReLoadAllClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any)) CORBA::Any *ReLoadAllClass::execute(Tango::DeviceImpl *device, TANGO_UNUSED(const CORBA::Any &in_any))
{ {
cout2 << "ReLoadAllClass::execute(): arrived" << endl; TANGO_LOG_INFO << "ReLoadAllClass::execute(): arrived" << endl;
((static_cast<AlarmHandler *>(device))->re_load_all()); ((static_cast<AlarmHandler *>(device))->re_load_all());
return new CORBA::Any(); return new CORBA::Any();
} }
...@@ -789,7 +784,7 @@ void AlarmHandlerClass::device_factory(const Tango::DevVarStringArray *devlist_p ...@@ -789,7 +784,7 @@ void AlarmHandlerClass::device_factory(const Tango::DevVarStringArray *devlist_p
// Create devices and add it into the device list // Create devices and add it into the device list
for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) for (unsigned long i=0 ; i<devlist_ptr->length() ; i++)
{ {
cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; TANGO_LOG_DEBUG << "Device name : " << (*devlist_ptr)[i].in() << endl;
device_list.push_back(new AlarmHandler(this, (*devlist_ptr)[i])); device_list.push_back(new AlarmHandler(this, (*devlist_ptr)[i]));
} }
...@@ -1437,7 +1432,7 @@ void AlarmHandlerClass::create_static_attribute_list(vector<Tango::Attr *> &att_ ...@@ -1437,7 +1432,7 @@ void AlarmHandlerClass::create_static_attribute_list(vector<Tango::Attr *> &att_
defaultAttList.push_back(att_name); defaultAttList.push_back(att_name);
} }
cout2 << defaultAttList.size() << " attributes in default list" << endl; TANGO_LOG_INFO << defaultAttList.size() << " attributes in default list" << endl;
/*----- PROTECTED REGION ID(AlarmHandlerClass::create_static_att_list) ENABLED START -----*/ /*----- PROTECTED REGION ID(AlarmHandlerClass::create_static_att_list) ENABLED START -----*/
...@@ -1473,7 +1468,7 @@ void AlarmHandlerClass::erase_dynamic_attributes(const Tango::DevVarStringArray ...@@ -1473,7 +1468,7 @@ void AlarmHandlerClass::erase_dynamic_attributes(const Tango::DevVarStringArray
vector<string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); vector<string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name);
if (ite_str == defaultAttList.end()) if (ite_str == defaultAttList.end())
{ {
cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; TANGO_LOG_INFO << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl;
Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str());
dev->remove_attribute(att_list[att.get_attr_idx()], true, false); dev->remove_attribute(att_list[att.get_attr_idx()], true, false);
--ite_att; --ite_att;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#ifndef AlarmHandlerClass_H #ifndef AlarmHandlerClass_H
#define AlarmHandlerClass_H #define AlarmHandlerClass_H
#include <tango.h> #include <tango/tango.h>
#include <AlarmHandler.h> #include <AlarmHandler.h>
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
// (Program Obviously used to Generate tango Object) // (Program Obviously used to Generate tango Object)
//============================================================================= //=============================================================================
#include <tango.h> #include <tango/tango.h>
#include <AlarmHandlerClass.h> #include <AlarmHandlerClass.h>
// Add class header files if needed // Add class header files if needed
......
static const char *RcsId = "$Header: /home/cvsadm/cvsroot/fermi/servers/hdb++/hdb++es/src/SubscribeThread.cpp,v 1.6 2014-03-06 15:21:43 graziano Exp $";
//+=============================================================================
//
// file : HdbEventHandler.cpp
//
// description : C++ source for thread management
// project : TANGO Device Server
//
// $Author: graziano $
//
// $Revision: 1.6 $
//
// $Log: SubscribeThread.cpp,v $
// Revision 1.6 2014-03-06 15:21:43 graziano
// StartArchivingAtStartup,
// start_all and stop_all,
// archiving of first event received at subscribe
//
// Revision 1.5 2014-02-20 14:59:02 graziano
// name and path fixing
// removed start acquisition from add
//
// Revision 1.4 2013-09-24 08:42:21 graziano
// bug fixing
//
// Revision 1.3 2013-09-02 12:13:22 graziano
// cleaned
//
// Revision 1.2 2013-08-23 10:04:53 graziano
// development
//
// Revision 1.1 2013-07-17 13:37:43 graziano
// *** empty log message ***
//
//
//
// copyleft : European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
//-=============================================================================
#include "AlarmHandler.h" #include "AlarmHandler.h"
#include "event_table.h" #include "event_table.h"
......
//=============================================================================
//
// file : HdbEventHandler.h
//
// description : Include for the HDbDevice class.
//
// project : Tango Device Server
//
// $Author: graziano $
//
// $Revision: 1.5 $
//
// $Log: SubscribeThread.h,v $
// Revision 1.5 2014-03-06 15:21:43 graziano
// StartArchivingAtStartup,
// start_all and stop_all,
// archiving of first event received at subscribe
//
// Revision 1.4 2013-09-24 08:42:21 graziano
// bug fixing
//
// Revision 1.3 2013-09-02 12:11:32 graziano
// cleaned
//
// Revision 1.2 2013-08-23 10:04:53 graziano
// development
//
// Revision 1.1 2013-07-17 13:37:43 graziano
// *** empty log message ***
//
//
//
// copyleft : European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
//=============================================================================
#ifndef _SUBSCRIBE_THREAD_H #ifndef _SUBSCRIBE_THREAD_H
#define _SUBSCRIBE_THREAD_H #define _SUBSCRIBE_THREAD_H
#include <tango.h> #include <tango/tango.h>
#include <eventconsumer.h>
#include <stdint.h> #include <stdint.h>
#include "event_table.h" #include "event_table.h"
/** // constants definitions here.
* @author $Author: graziano $ //-----------------------------------------------
* @version $Revision: 1.5 $
*/
// constants definitions here.
//-----------------------------------------------
namespace AlarmHandler_ns namespace AlarmHandler_ns
{ {
......
/* /*
* alarm-thread.cpp * alarm-thread.cpp
* *
* $Author: claudio $
*
* $Revision: 1.7 $
*
* $Log: alarm-thread.cpp,v $
* Revision 1.7 2015-07-21 13:40:59 claudio
* minor cleanups
*
* Revision 1.6 2013-03-06 10:41:11 claudio
* commented out debug print statements
*
* Revision 1.5 2008-07-08 12:11:39 graziano
* omni_thread_fatal exception handling
*
* Revision 1.4 2008/07/07 09:13:12 graziano
* omni_thread_fatal exception handling
*
* Revision 1.3 2008/04/24 06:51:34 graziano
* small code cleanings
*
*
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale * copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park * Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY * 34012 Basovizza, Trieste ITALY
...@@ -36,7 +14,7 @@ static const char __FILE__rev[] = __FILE__ " $Revision: 1.7 $"; ...@@ -36,7 +14,7 @@ static const char __FILE__rev[] = __FILE__ " $Revision: 1.7 $";
*/ */
alarm_thread::alarm_thread(AlarmHandler_ns::AlarmHandler *p) : p_Alarm(p) alarm_thread::alarm_thread(AlarmHandler_ns::AlarmHandler *p) : p_Alarm(p)
{ {
//cout << __FILE__rev << endl; //TANGO_LOG << __FILE__rev << endl;
} }
/* /*
...@@ -142,21 +120,21 @@ void alarm_thread::run(void *) ...@@ -142,21 +120,21 @@ void alarm_thread::run(void *)
ostringstream err; ostringstream err;
err << "omni_thread_fatal exception running alarm thread, err=" << ex.error << ends; err << "omni_thread_fatal exception running alarm thread, err=" << ex.error << ends;
//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl; //WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;
printf("alarm_thread::run(): %s", err.str().c_str()); printf("alarm_thread::run(): %s\n", err.str().c_str());
} }
catch(Tango::DevFailed& ex) catch(Tango::DevFailed& ex)
{ {
ostringstream err; ostringstream err;
err << "exception running alarm thread: '" << ex.errors[0].desc << "'" << ends; err << "exception running alarm thread: '" << ex.errors[0].desc << "'" << ends;
//WARN_STREAM << "alarm_thread::run(): " << err.str() << endl; //WARN_STREAM << "alarm_thread::run(): " << err.str() << endl;
printf("alarm_thread::run(): %s", err.str().c_str()); printf("alarm_thread::run(): %s\n", err.str().c_str());
Tango::Except::print_exception(ex); //Tango::Except::print_exception(ex);
} }
catch(...) catch(...)
{ {
//WARN_STREAM << "alarm_thread::run(): catched unknown exception!!" << endl; //WARN_STREAM << "alarm_thread::run(): catched unknown exception!!" << endl;
printf("alarm_thread::run(): catched unknown exception!!"); printf("alarm_thread::run(): catched unknown exception!!\n");
} }
} }
//cout << "alarm_thread::run(): returning" << endl; //TANGO_LOG << "alarm_thread::run(): returning" << endl;
} /* alarm_thread::run() */ } /* alarm_thread::run() */
/* /*
* alarm-thread.h * alarm-thread.h
* *
* $Author: graziano $
*
* $Revision: 1.3 $
*
* $Log: alarm-thread.h,v $
* Revision 1.3 2008-04-23 15:00:57 graziano
* small code cleanings
*
*
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale * copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park * Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY * 34012 Basovizza, Trieste ITALY
...@@ -20,7 +10,7 @@ ...@@ -20,7 +10,7 @@
#define ALARM_THREAD_H #define ALARM_THREAD_H
#include <omnithread.h> #include <omnithread.h>
#include <tango.h> #include <tango/tango.h>
#include <AlarmHandler.h> #include <AlarmHandler.h>
#define ALARM_THREAD_EXIT "alarm_thread_exit" #define ALARM_THREAD_EXIT "alarm_thread_exit"
......