Have working monitorlink expressions
parent
e4bd2d351a
commit
1798d95b8b
|
@ -1 +1 @@
|
|||
Subproject commit 1b40f1661f93f50fd5805f239d1e466a3bcf888f
|
||||
Subproject commit eab32851421ffe54fec0229c3efc44c642bc8d46
|
|
@ -307,6 +307,7 @@ public:
|
|||
bool isAlarmed();
|
||||
bool inAlarm();
|
||||
bool hasAlarmed();
|
||||
int score();
|
||||
};
|
||||
protected:
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ bool Monitor::MonitorLink::connect() {
|
|||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return connected;
|
||||
} // end bool Monitor::MonitorLink::connect()
|
||||
|
||||
bool Monitor::MonitorLink::disconnect() {
|
||||
|
@ -214,17 +214,21 @@ bool Monitor::MonitorLink::inAlarm() {
|
|||
return( shared_data->state == ALARM || shared_data->state == ALERT );
|
||||
}
|
||||
|
||||
bool Monitor::MonitorLink::hasAlarmed() {
|
||||
int Monitor::MonitorLink::score() {
|
||||
if (zone_id and (zone_index >= 0)) {
|
||||
Debug(1, "Checking zone %u, zone_index is %d, score is %d", zone_id, zone_index, zone_scores[zone_index]);
|
||||
if (zone_scores[zone_index] > 0) {
|
||||
return true;
|
||||
}
|
||||
return zone_scores[zone_index];
|
||||
}
|
||||
if (shared_data->state == ALARM) {
|
||||
Debug(1, "State is %d", shared_data->state);
|
||||
return true;
|
||||
Debug(1, "Checking all zones score is %d", shared_data->last_frame_score);
|
||||
return shared_data->last_frame_score;
|
||||
}
|
||||
Debug(1, "not alarmed. %d", shared_data->state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Monitor::MonitorLink::hasAlarmed() {
|
||||
return this->score() > 0;
|
||||
last_event_id = shared_data->last_event_id;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -60,30 +60,35 @@ bool MonitorLinkExpression::evaluate() {
|
|||
Warning("%s", std::string(result.message).c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return result.score > 0;
|
||||
}
|
||||
|
||||
MonitorLinkExpression::result
|
||||
MonitorLinkExpression::visit(Node const & node) {
|
||||
Debug(1, "visit: Node: %p", &node);
|
||||
//Debug(1, "visit: Node: left %p right: %p", node.left, node.right);
|
||||
Debug(1, "visit: Node: %p Token: %d value %s",
|
||||
&node,
|
||||
static_cast<int>(node.token.type()),
|
||||
std::string(node.token.value()).c_str()
|
||||
);
|
||||
if (node.token.type() == Token::TokenType::monitorlink) {
|
||||
return { true, node.token.value() };
|
||||
Debug(1, "Have monitorlink, return true, value");
|
||||
return { true, "", node.token.score() };
|
||||
} else if (nullptr == node.left || nullptr == node.right) {
|
||||
return { false, "Missing operand" };
|
||||
return { false, "Missing operand", 0 };
|
||||
}
|
||||
Debug(1, "Token: %d", static_cast<int>(node.token.type()));
|
||||
Debug(1, "Token: value %s", std::string(node.token.value()).c_str());
|
||||
|
||||
switch ( node.token.type() ) {
|
||||
switch (node.token.type()) {
|
||||
case Token::TokenType::logical_and:
|
||||
Debug(1, "and");
|
||||
return visit_logical_and(node);
|
||||
case Token::TokenType::logical_or :
|
||||
Debug(1, "or");
|
||||
Debug(1, "or");
|
||||
return visit_logical_or(node);
|
||||
case Token::TokenType::logical_comma :
|
||||
Debug(1, "comma");
|
||||
Debug(1, "comma");
|
||||
return visit_logical_or(node);
|
||||
default:
|
||||
Debug(1, "unknown");
|
||||
return { false, "Unknown token type" };
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +104,10 @@ MonitorLinkExpression::visit_logical_and(MonitorLinkExpression::Node const & nod
|
|||
left.message.empty() ? right.message : left.message
|
||||
};
|
||||
|
||||
return { left.success && right.success, message };
|
||||
Debug(1, "aND left score %d right score %d", left.score, right.score);
|
||||
return { left.success && right.success, message,
|
||||
((left.score and right.score) ? left.score + right.score : 0)
|
||||
};
|
||||
}
|
||||
|
||||
MonitorLinkExpression::result
|
||||
|
@ -113,7 +121,12 @@ MonitorLinkExpression::visit_logical_or(MonitorLinkExpression::Node const & node
|
|||
left.message.empty() ? right.message : left.message
|
||||
};
|
||||
|
||||
return { left.success || right.success, message };
|
||||
Debug(1, "Or left score %d right score %d", left.score, right.score);
|
||||
return {
|
||||
left.success || right.success,
|
||||
message,
|
||||
((left.score or right.score) ? left.score + right.score : 0)
|
||||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<MonitorLinkExpression::Node>
|
||||
|
@ -126,12 +139,8 @@ MonitorLinkExpression::parse_expression( Tokens const & tokens, std::size_t & cu
|
|||
|
||||
// First token could me a parenthesis or monitorlink. Otherwise invalid.
|
||||
|
||||
//auto left{ std::make_unique<Node>(tokens[current]) };
|
||||
//if ( tokens[current].is(
|
||||
auto left{ parse_and_operation(tokens, current) };
|
||||
|
||||
//parse_and_operation(tokens, current) };
|
||||
|
||||
/*
|
||||
if (
|
||||
has_unused(tokens, current)
|
||||
and
|
||||
|
@ -142,24 +151,34 @@ MonitorLinkExpression::parse_expression( Tokens const & tokens, std::size_t & cu
|
|||
Debug(1, "parse_expression: not or, Returning left %s", std::string(left->token.value()).c_str());
|
||||
return left;
|
||||
}
|
||||
*/
|
||||
|
||||
std::unique_ptr<MonitorLinkExpression::Node> left;
|
||||
/*
|
||||
if (tokens[current].is(Token::TokenType::monitorlink)) {
|
||||
Debug(1, "Left is a monitorlink");
|
||||
left = std::make_unique<Node>(tokens[current]);
|
||||
current++;
|
||||
} else {
|
||||
Debug(1, "Left is not a monitorlink, parsing and");
|
||||
left = parse_and_operation(tokens, current);
|
||||
// invalid
|
||||
//return nullptr;
|
||||
}
|
||||
*/
|
||||
|
||||
while (has_unused(tokens, current) && tokens[ current ].is( Token::TokenType::logical_or )) {
|
||||
while (has_unused(tokens, current) and
|
||||
(
|
||||
tokens[current].is(Token::TokenType::logical_or)
|
||||
or
|
||||
tokens[current].is(Token::TokenType::logical_comma)
|
||||
)
|
||||
) {
|
||||
Debug(1, "Have or adding it");
|
||||
|
||||
auto logical_or{ std::make_unique<Node>( Token::TokenType::logical_or ) };
|
||||
current++;
|
||||
|
||||
auto right{ parse_and_operation( tokens, current ) };
|
||||
if ( right == nullptr ) {
|
||||
if (right == nullptr) {
|
||||
Debug(1, "null from right side");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -208,8 +227,11 @@ MonitorLinkExpression::parse_and_operation( Tokens const & tokens, std::size_t &
|
|||
}
|
||||
|
||||
std::unique_ptr<MonitorLinkExpression::Node>
|
||||
MonitorLinkExpression::parse_parentheses(Tokens const & tokens, std::size_t & current) {
|
||||
if (!has_unused(tokens, current)) return nullptr;
|
||||
MonitorLinkExpression::parse_parentheses(Tokens const &tokens, std::size_t ¤t) {
|
||||
if (!has_unused(tokens, current)) {
|
||||
Debug(1, "No unused...");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (tokens[current].is(Token::TokenType::lp)) {
|
||||
++current;
|
||||
|
@ -221,6 +243,11 @@ MonitorLinkExpression::parse_parentheses(Tokens const & tokens, std::size_t & cu
|
|||
if (tokens[ current++ ].is(Token::TokenType::rp)) {
|
||||
return expression;
|
||||
}
|
||||
} else if (tokens[current].is(Token::TokenType::monitorlink)) {
|
||||
Debug(1, "Have monitorlink, returning it");
|
||||
auto link {std::make_unique<Node>(tokens[current])};
|
||||
current++;
|
||||
return link;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -66,6 +66,7 @@ class MonitorLinkExpression {
|
|||
* Message in case of the fault.
|
||||
*/
|
||||
std::string_view message{};
|
||||
int score {-1};
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -55,6 +55,7 @@ class Token {
|
|||
token_type_pair{ "(", TokenType::lp },
|
||||
token_type_pair{ ")", TokenType::rp }
|
||||
};
|
||||
|
||||
//constexpr TokenType to_token_type( std::string_view const value ) noexcept;
|
||||
constexpr TokenType to_token_type( std::string_view const value ) noexcept {
|
||||
auto find_matching {
|
||||
|
@ -71,50 +72,49 @@ class Token {
|
|||
}
|
||||
};
|
||||
|
||||
if (
|
||||
auto const symbol{ find_matching( symbols ) };
|
||||
symbol != std::cend( symbols )
|
||||
) {
|
||||
auto const symbol{ find_matching(symbols) };
|
||||
if (symbol != std::cend(symbols)) {
|
||||
return symbol->second;
|
||||
}
|
||||
|
||||
return TokenType::monitorlink;
|
||||
}
|
||||
} // end constexpr TokenType to_token_type( std::string_view const value )
|
||||
|
||||
public:
|
||||
|
||||
Token(TokenType const type, std::string_view const value)
|
||||
: type_(type)
|
||||
, value_(value)
|
||||
, monitor_link_(nullptr)
|
||||
{
|
||||
if (type_ == TokenType::monitorlink) {
|
||||
auto colon_position = value_.find(':');
|
||||
unsigned int monitor_id = 0;
|
||||
unsigned int zone_id = 0;
|
||||
std::string monitor_name;
|
||||
std::string zone_name;
|
||||
{
|
||||
if (type_ == TokenType::monitorlink) {
|
||||
auto colon_position = value_.find(':');
|
||||
unsigned int monitor_id = 0;
|
||||
unsigned int zone_id = 0;
|
||||
std::string monitor_name;
|
||||
std::string zone_name;
|
||||
|
||||
if (colon_position != std::string::npos) {
|
||||
// Has a zone specification
|
||||
monitor_id = std::stoul(std::string(value_.substr(0, colon_position)));
|
||||
zone_id = std::stoul(std::string(value_.substr(colon_position+1, std::string::npos)));
|
||||
if (colon_position != std::string::npos) {
|
||||
// Has a zone specification
|
||||
monitor_id = std::stoul(std::string(value_.substr(0, colon_position)));
|
||||
zone_id = std::stoul(std::string(value_.substr(colon_position+1, std::string::npos)));
|
||||
} else {
|
||||
monitor_id = std::stoul(std::string(value_));
|
||||
}
|
||||
Debug(1, "Have linked monitor %d zone %d", monitor_id, zone_id);
|
||||
|
||||
std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
|
||||
monitor_link_ = new Monitor::MonitorLink(monitor, zone_id);
|
||||
} else {
|
||||
monitor_id = std::stoul(std::string(value_));
|
||||
Debug( 1, "Not a monitor link value is %s", std::string(value_).c_str());
|
||||
}
|
||||
Debug(1, "Have linked monitor %d zone %d", monitor_id, zone_id);
|
||||
|
||||
std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
|
||||
monitor_link_ = new Monitor::MonitorLink(monitor, zone_id);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr Token() noexcept :
|
||||
type_(TokenType::unknown),
|
||||
value_(""),
|
||||
monitor_link_(nullptr)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
//Token( TokenType const type, std::string_view const value );
|
||||
|
||||
constexpr Token( Token && rhs ) noexcept = default;
|
||||
|
@ -126,11 +126,33 @@ class Token {
|
|||
, monitor_link_(nullptr)
|
||||
{}
|
||||
|
||||
constexpr Token( std::string_view const value ) noexcept
|
||||
Token( std::string_view const value ) noexcept
|
||||
: type_ (to_token_type(value))
|
||||
, value_(value)
|
||||
, monitor_link_(nullptr)
|
||||
{}
|
||||
{
|
||||
if (type_ == TokenType::monitorlink) {
|
||||
auto colon_position = value_.find(':');
|
||||
unsigned int monitor_id = 0;
|
||||
unsigned int zone_id = 0;
|
||||
std::string monitor_name;
|
||||
std::string zone_name;
|
||||
|
||||
if (colon_position != std::string::npos) {
|
||||
// Has a zone specification
|
||||
monitor_id = std::stoul(std::string(value_.substr(0, colon_position)));
|
||||
zone_id = std::stoul(std::string(value_.substr(colon_position+1, std::string::npos)));
|
||||
} else {
|
||||
monitor_id = std::stoul(std::string(value_));
|
||||
}
|
||||
Debug(1, "Have linked monitor %d zone %d", monitor_id, zone_id);
|
||||
|
||||
std::shared_ptr<Monitor> monitor = Monitor::Load(monitor_id, false, Monitor::QUERY);
|
||||
monitor_link_ = new Monitor::MonitorLink(monitor, zone_id);
|
||||
} else {
|
||||
Debug( 1, "Not a monitor link value is %s", std::string(value_).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Token & operator=( Token && rhs ) noexcept = default;
|
||||
Token & operator=( Token const & rhs ) noexcept = default;
|
||||
|
@ -145,6 +167,7 @@ class Token {
|
|||
type_ = type;
|
||||
value_ = "";//to_token_keyword( type );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
constexpr TokenType type() const noexcept { return type_; }
|
||||
|
@ -152,6 +175,7 @@ class Token {
|
|||
constexpr void value( std::string_view const value ) noexcept {
|
||||
type_ = to_token_type( value );
|
||||
value_ = value;
|
||||
|
||||
}
|
||||
|
||||
[[ nodiscard ]] constexpr std::string_view value() const noexcept {
|
||||
|
@ -174,6 +198,26 @@ class Token {
|
|||
return is(first) || is(second);
|
||||
}
|
||||
|
||||
[[ nodiscard ]] constexpr bool hasAlarmed() const {
|
||||
return (monitor_link_ && monitor_link_->connect() && monitor_link_->hasAlarmed());
|
||||
}
|
||||
|
||||
[[ nodiscard ]] constexpr int score() const {
|
||||
if ( monitor_link_ ) {
|
||||
if (!monitor_link_->isConnected() ) {
|
||||
Debug(1, "connecting");
|
||||
if (!monitor_link_->connect()) {
|
||||
Debug(1, "failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int s = monitor_link_->score();
|
||||
Debug(1, "Score from monitor %s is %d", monitor_link_->Name(), s);
|
||||
return s;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
TokenType type_;
|
||||
std::string_view value_;
|
||||
|
|
Loading…
Reference in New Issue