Have working monitorlink expressions

pull/3530/head
Isaac Connor 2022-07-14 17:25:51 -04:00
parent e4bd2d351a
commit 1798d95b8b
6 changed files with 134 additions and 57 deletions

@ -1 +1 @@
Subproject commit 1b40f1661f93f50fd5805f239d1e466a3bcf888f
Subproject commit eab32851421ffe54fec0229c3efc44c642bc8d46

View File

@ -307,6 +307,7 @@ public:
bool isAlarmed();
bool inAlarm();
bool hasAlarmed();
int score();
};
protected:

View File

@ -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;
}

View File

@ -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 &current) {
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;

View File

@ -66,6 +66,7 @@ class MonitorLinkExpression {
* Message in case of the fault.
*/
std::string_view message{};
int score {-1};
};
public:

View File

@ -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_;