--- a
+++ b/backend/smartRuleSystem.js
@@ -0,0 +1,250 @@
+/*made by Miguel Rodrigues @ KBZ miguel.rodrigues@knowledgebiz.pt*/
+
+//smartRuleSystem is to automatically and intelligently create new rules
+
+var mysql = require('../controllers/mysql');
+var email = require('../controllers/emailer');
+var logger = require('../config/logger.js');
+var predict = require('predict');
+
+//Handle the rules system and creates Automatically New Rules
+module.exports.smartRulesHandler = function(){
+ var handler = "backend.controllers.mysql.getRulesList";
+ logger.info("Starting: ",handler);
+ //Get All Rules on Specific Rule
+ mysql.getRulesList(function(isOK, rules){
+ if(isOK){
+ logger.info("GetRulesList Success");
+ rules.forEach(function(eachRule, ruleIndex){
+ var handler = "backend.controllers.mysql.retrieveStatisticsList";
+ logger.info("Starting: ",handler);
+ //Get Statistics on Specific Rule
+ mysql.retrieveStatisticsList(eachRule.rulesID, function(isOK, rows, total){
+ if(isOK){
+ if(total.totalNotifications > 0){
+ switch (eachRule.conditionValue){
+ case ">":
+ case ">=":
+ if(eachRule.description.search("System Create Automatically New rule") > -1){
+ if(total.averageValue < parseFloat(eachRule.threshold / 100)*parseFloat(eachRule.controlValue)){
+ updateRule(eachRule, 0);
+ }else if(total.averageValue < parseFloat(eachRule.controlValue)){
+ checkLastFalseNotifications(eachRule, function(isOK, newValue){
+ if(isOK) {
+ updateRule(eachRule, newValue);
+ }
+ })
+ }else{
+ deleteRule(eachRule.rulesID);
+ }
+ }else{
+ checkIfExists(eachRule, function(OK, callback){
+ if(!OK) {
+ if(total.averageValue < parseFloat(eachRule.threshold / 100)*parseFloat(eachRule.controlValue)){
+ createNewRule(eachRule, 0);
+ }else if(total.averageValue < parseFloat(eachRule.controlValue)){
+ checkLastFalseNotifications(eachRule, function(isOK, newValue){
+ if(isOK) {
+ createNewRule(eachRule, newValue);
+ }
+ })
+ }
+ }
+ })
+ }
+ break;
+ case "<":
+ case "<=":
+ if(eachRule.description.search("System Create Automatically New rule") > -1){
+ if(total.averageValue > parseFloat(eachRule.threshold / 100)*parseFloat(eachRule.controlValue)){
+ updateRule(eachRule, 0);
+ }else if(total.averageValue > parseFloat(eachRule.controlValue)){
+ checkLastFalseNotifications(eachRule, function(isOK, newValue){
+ if(isOK) {
+ updateRule(eachRule, newValue);
+ }
+ })
+ }else{
+ deleteRule(eachRule.rulesID);
+ }
+ }else{
+ checkIfExists(eachRule, function(OK, callback){
+ if(!OK) {
+ if(total.averageValue > parseFloat(eachRule.threshold / 100)*parseFloat(eachRule.controlValue)){
+ createNewRule(eachRule, 0);
+ }else if(total.averageValue > parseFloat(eachRule.controlValue)){
+ checkLastFalseNotifications(eachRule, function(isOK, newValue){
+ if(isOK) {
+ createNewRule(eachRule, newValue);
+ }
+ })
+ }
+ }
+ })
+ }
+ break;
+ default:
+ }
+ }
+ }
+ else{
+ logger.error("retrieveStatisticsList Failed: ", rows);
+ }
+ })
+ })
+ }else{
+ logger.error("GetRulesList Failed: ", rules);
+ }
+ })
+}
+
+//Function for Update Data on Specific Rule
+/*
+input: rule (Specific Rule), newConditionValue
+*/
+function updateRule (rule, newConditionValue){
+ var handler = "backend.controllers.mysql.updateRule";
+
+ if(newConditionValue == 0){
+ var data = {
+ description: "System Create Automatically New rule: " + rule.description,
+ parameter: rule.parameter,
+ conditionValue: rule.conditionValue,
+ controlValue: parseFloat(rule.threshold / 100)*parseFloat(rule.controlValue),
+ threshold: rule.threshold,
+ notificationType: rule.notificationType,
+ token: rule.token
+ };
+ }else if(newConditionValue > 0){
+ var data = {
+ description: "System Create Automatically New rule: " + rule.description,
+ parameter: rule.parameter,
+ conditionValue: rule.conditionValue,
+ controlValue: newConditionValue,
+ threshold: rule.threshold,
+ notificationType: rule.notificationType,
+ token: rule.token
+ };
+ }
+ mysql.updateRule(data, function(isOK, callback){
+ if(!isOK) {
+ logger.error(handler,"Fail");
+ }else{
+ logger.info(handler,"Success");
+ }
+ });
+}
+
+//Function for Delete Specific Rule
+/*
+input: rulesID (Specific Rule)
+*/
+function deleteRule (rulesID){
+ var handler = "backend.controllers.mysql.deleteRule";
+ mysql.deleteRule(rulesID, function(isOK, callback){
+ if(!isOK) {
+ logger.error(handler,"Fail");
+ }else{
+ logger.info(handler,"Success");
+ }
+ })
+}
+
+//Function for Create New Rule (Automatically New Rule by System)
+/*
+input: rule (Specific Rule), newConditionValue
+*/
+function createNewRule (rule, newConditionValue){
+ if(newConditionValue == 0){
+ var data = {
+ description: "System Create Automatically New rule: " + rule.description,
+ parameter: rule.parameter,
+ conditionValue: rule.conditionValue,
+ controlValue: parseFloat(rule.threshold / 100)*parseFloat(rule.controlValue),
+ threshold: rule.threshold,
+ notificationType: rule.notificationType,
+ token: rule.token
+ };
+ }else if(newConditionValue > 0){
+ var data = {
+ description: "System Create Automatically New rule: " + rule.description,
+ parameter: rule.parameter,
+ conditionValue: rule.conditionValue,
+ controlValue: newConditionValue,
+ threshold: rule.threshold,
+ notificationType: rule.notificationType,
+ token: rule.token
+ };
+ }
+ var handler = "backend.controllers.mysql.insertNotificationRules";
+ logger.info("Starting: ",handler);
+ mysql.insertNotificationRules(data, function(isOK, callback){
+ if(!isOK) {
+ logger.error("Create Automatically New Rule: Fail");
+ }
+ else{
+ logger.info("Create Automatically New Rule: Sucess");
+ var handler = "backend.controllers.mysql.getEmailTovAppByToken";
+ logger.info("Starting: ",handler);
+ mysql.getEmailTovAppByToken(rule.token, function(isOK, emailTo){
+ if(!isOK) {
+ logger.error("Error Get Email by Token");
+ }
+ else{
+ logger.info("Success Get Email by Token");
+ email.sendEmailNewRule(emailTo[0].developerID, "System Create Automatically New rule: " + rule.description);
+ }
+ })
+ }
+ })
+}
+
+//Function for Check if that Specific Automatically Rule Created by System Exists
+/*
+input: rule (Specific Rule)
+output: true/false
+*/
+function checkIfExists (rule, cb){
+ mysql.checkIfRuleAutomaticExists(rule, function(isOK, callback){
+ if(!isOK) {
+ logger.info("There is no Rule Created Automatically");
+ cb(false);
+ }
+ else{
+ logger.info("Rule already Created");
+ cb(true);
+ }
+ })
+}
+
+//Function for get Last 5 False Notifications
+/*
+input: rule (Specific Rule)
+output: true/false
+*/
+function checkLastFalseNotifications (rule, cb){
+ var prediction = predict.movingAverage(5);
+ var aux = 0;
+ mysql.retrieveStatisticsList(rule.rulesID, function(isOK, rows){
+ if(!isOK) {
+ cb(false);
+ }
+ else{
+ if(rows.length > 0){
+ rows.slice(-5).forEach(function(eachRow, index){
+ if(eachRow.result == "false"){
+ prediction.pushValues([parseFloat(eachRow.subjectValue)]);
+ aux++;
+ }
+ })
+ if(aux == 5){
+ cb(true, prediction.predictNextValue().toFixed(2));
+ }else{
+ cb(false);
+ }
+ }else{
+ cb(false);
+ }
+ }
+ })
+}