/// <summary> /// Constructor taking a SerialCommunicator object so as to allow COM settings to be /// implemented. /// </summary> /// <param name="communicator"></param> public SerialDataHandler(SerialCommunicator communicator, Rule rule, Value value) { //Create temp variable to read the required values. var comm = (SerialCommunicator) communicator; //Initialise the COM Port settings. _sPort = new SerialPort(comm.ComPort) { BaudRate = comm.BaudRate, Parity = Parity.None, StopBits = StopBits.One, DataBits = comm.DataBits, Handshake = Handshake.None, DtrEnable=comm.IsDTR, RtsEnable = comm.IsRTS }; //Make the Value available. _value = value; //Output the data required - any instance of [val] is replaced with the actual value StringBuilder builder = new StringBuilder(rule.Action.OutputValue); builder.Replace("[val]", _value.StringValue); //Output the string OutputValue(builder.ToString()); }
/// <summary> /// Create a new Rule on the database. /// </summary> /// <param name="rule"></param> public Rule CreateRule(Rule rule) { //Create new rule and store the new object. var newObj = _repo.CreateRule(rule); //Add the new rule to the list of rules. _rules.Add(newObj); //Return the new rule to the caller. return newObj; }
/// <summary> /// Constructor takes a database communicator object. /// </summary> /// <param name="comms">Database Communicator Model</param> public DatabaseHandler(DatabaseCommunicator comms, Rule rule, Value value) { _communicator = comms; dcm = new DatabaseConnectionManager(comms.DbType, comms.ConnectionString, comms.Query, true); //Make the Value available. _value = value; //Output the data required - any instance of [val] is replaced with the actual value StringBuilder builder = new StringBuilder(rule.Action.OutputValue); builder.Replace("[val]", _value.StringValue); //Output the string OutputValue(builder.ToString()); }
/// <summary> /// Constructor takes a file communicator object. /// </summary> /// <param name="comms">File Communicator Model</param> public FlatFileHandler(FileCommunicator comms, Rule rule, Value val) { //Set the Communicator object. _communicator = comms; //Configure the local File Path variables. _filePath = comms.FilePath; //Give access to the value. _value = val; //Output the data required - any instance of [val] is replaced with the actual value StringBuilder builder = new StringBuilder(rule.Action.OutputValue); builder.Replace("[val]", _value.StringValue); //Output the string OutputValue(builder.ToString()); }
/// <summary> /// Updates a Rule that already exists on the database. /// </summary> /// <param name="rule"></param> /// <returns></returns> public Rule UpdateRule(Rule rule) { return _repo.UpdateRule(rule); }
private void WriteData(Rule rule, Value value) { var controller = new CommunicatorController(); var comm = controller.GetAllCommunicators().FirstOrDefault(com => com.Id == rule.Action.CommunicatorId); if (comm == null) return; DataHandler handler = null; switch (comm.Type) { case CommunicatorType.FlatFile: handler = new FlatFileHandler((FileCommunicator)comm,rule,value); break; case CommunicatorType.Serial: handler = new SerialDataHandler((SerialCommunicator)comm,rule,value); break; case CommunicatorType.Database: handler = new DatabaseHandler((DatabaseCommunicator)comm,rule,value); break; default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// When a Rule's critera have been met, this method is called to execute any /// and all Actions as per the Rule's settings. /// An Alarm is also raised from here. /// </summary> /// <param name="rule">The passed rule.</param> /// <param name="value">The value that passed the rule.</param> private void TakeAction(Rule rule, Value value) { //Handle any requirement to Alarm. if (rule.Alarm) { //Create accessor to the AlarmController class. var controller = new AlarmController(); //Create a new Alarm object as per the model. var alarm = new Alarm() { //Id = Guid.NewGuid(), Rule = rule, RuleId = rule.Id, Device = rule.Device, DeviceId = rule.DeviceId, Value = value, ValueId = value.Id, TimeStamp = value.EventTime, Accepted = false }; //Pass the alarm object to the AlarmController. controller.CreateAlarm(alarm); } var actionController = new ActionController(); var act = actionController.RetrieveActionsForRule(rule.Id).FirstOrDefault(); //Handle any Actions to be taken. if (act != null) { rule.Action = act; WriteData(rule,value); } }
/// <summary> /// Determines whether or not the Rule's criteria has been met depending on the values selected by the /// Rule. /// </summary> /// <param name="rule"></param> /// <param name="value"></param> /// <returns></returns> private bool CriteraMet(Rule rule, Value value) { //Prepare an error message to show if rule checking fails. var errorMsg = $"Could not check Rule {rule.Id} for '{rule.DeviceId}'! There may have been an issue with the RuleType?"; //Prepare to handle Rules of type 'Between' by pre-splitting the constraints. var betweenBreaker = '#'; string constraintValueOne="", constraintValueTwo=""; if (rule.RuleType == RuleType.Between) { //Attempt to split, if fail, print warning and fail the rule. try { //Constraint splitting. constraintValueOne = rule.Constraint.Substring(0, rule.Constraint.IndexOf(betweenBreaker)); constraintValueTwo = rule.Constraint.Substring( rule.Constraint.IndexOf(betweenBreaker)+1); } catch (Exception) { DebugOutput.Print($"The rule (#{rule.Id}) is set to investigate values between a set range, but this could not be understood. Check the constraint!"); return false; } } //Switching on the ValueType first as some values will not allow some RuleTypes (i.e. a string cannot be </>/<=/>=) switch (rule.ValueType) { case ValueType.String: switch (rule.RuleType) { case RuleType.EqualTo: return (value.StringValue.Trim().Equals(rule.Constraint.Trim())); case RuleType.Not: return (value.StringValue.Trim().Equals(rule.Constraint.Trim())); default: DebugOutput.Print(errorMsg); break; } break; case ValueType.Integer: switch (rule.RuleType) { case RuleType.LessThan: return (value.IntegerValue < ConvertInt(rule.Constraint)); case RuleType.LessThanEqualTo: return (value.IntegerValue <= ConvertInt(rule.Constraint)); case RuleType.EqualTo: return (value.IntegerValue == ConvertInt(rule.Constraint)); case RuleType.MoreThanEqualTo: return (value.IntegerValue >= ConvertInt(rule.Constraint)); case RuleType.MoreThan: return (value.IntegerValue > ConvertInt(rule.Constraint)); case RuleType.Not: return (value.IntegerValue != ConvertInt(rule.Constraint)); case RuleType.Between: return ((value.IntegerValue >= ConvertInt(constraintValueOne)) && (value.IntegerValue<=ConvertInt(constraintValueTwo))); default: DebugOutput.Print(errorMsg); break; } break; case ValueType.Float: switch (rule.RuleType) { case RuleType.LessThan: return (value.FloatValue < ConvertDecimal(rule.Constraint)); case RuleType.LessThanEqualTo: return (value.FloatValue <= ConvertDecimal(rule.Constraint)); case RuleType.EqualTo: return (value.FloatValue == ConvertDecimal(rule.Constraint)); case RuleType.MoreThanEqualTo: return (value.FloatValue >= ConvertDecimal(rule.Constraint)); case RuleType.MoreThan: return (value.FloatValue > ConvertDecimal(rule.Constraint)); case RuleType.Not: return (value.FloatValue != ConvertDecimal(rule.Constraint)); case RuleType.Between: return ((value.FloatValue>= ConvertDecimal(constraintValueOne)) && (value.FloatValue<= ConvertDecimal(constraintValueTwo))); default: DebugOutput.Print(errorMsg); break; } break; case ValueType.Boolean: switch (rule.RuleType) { case RuleType.EqualTo: return (value.BooleanValue == ConvertBool(rule.Constraint)); default: DebugOutput.Print(errorMsg); break; } break; default: DebugOutput.Print(errorMsg); break; } //Upon failure of conversion, the break statements will fall through. return false; }