using System; using System.Collections.Generic; using System.Net; namespace esh.core { public class Components { public class Sensor { public readonly string Mac; public string DataType; public string SensorType; public string Value; public string DisplayUnit; public DateTime LastUpdated; public string CustomName; public string CustomDescription; public Sensor(string mac) { Mac = mac; LastUpdated = DateTime.Now; } } public class Actor { public readonly string Mac; public IPAddress LastKnownIP; public string LastKnownState; public string ActorType; public string WantsDataType; public DateTime LastPing; public string CustomName; public string CustomDescription; public Actor(string mac) { Mac = mac; LastPing = DateTime.Now; } } public class Value { public enum ValueType { Integer, Boolean, Double, String } public ValueType Type; public string StringValue; } public class Trigger { public class Condition { public enum ConditionType { ValueExact, //when sensor value is EXACTLY x ThresholdRisingEdge, //when value goes above threshold ThresholdFallingEdge, //when value goes below threshold ValueChanged, //when sensor value is different than before TODO! Time //TODO: intervals and stuff } public ConditionType Type; public Value CheckValue; private bool thresholdCheck = false; public bool IsMet(Value sourceValue) { if (sourceValue.Type != CheckValue.Type) return false; switch (Type) { case ConditionType.ValueExact: return sourceValue.StringValue == CheckValue.StringValue; case ConditionType.ThresholdRisingEdge: switch (sourceValue.Type) { case Value.ValueType.Integer: if (int.Parse(sourceValue.StringValue) > int.Parse(CheckValue.StringValue) && !thresholdCheck) { thresholdCheck = true; return true; } else if (int.Parse(sourceValue.StringValue) < int.Parse(CheckValue.StringValue) && thresholdCheck) { thresholdCheck = false; } return false; case Value.ValueType.Boolean: if (bool.Parse(sourceValue.StringValue) == bool.Parse(CheckValue.StringValue) && !thresholdCheck) { thresholdCheck = true; return true; } else if (bool.Parse(sourceValue.StringValue) != bool.Parse(CheckValue.StringValue) && thresholdCheck) { thresholdCheck = false; } return false; case Value.ValueType.Double: if (double.Parse(sourceValue.StringValue) > double.Parse(CheckValue.StringValue) && !thresholdCheck) { thresholdCheck = true; return true; } else if (double.Parse(sourceValue.StringValue) < double.Parse(CheckValue.StringValue) && thresholdCheck) { thresholdCheck = false; } return false; case Value.ValueType.String: return false; default: throw new ArgumentOutOfRangeException(); } case ConditionType.ThresholdFallingEdge: switch (sourceValue.Type) { case Value.ValueType.Integer: if (int.Parse(sourceValue.StringValue) < int.Parse(CheckValue.StringValue) && !thresholdCheck) { thresholdCheck = true; return true; } else if (int.Parse(sourceValue.StringValue) > int.Parse(CheckValue.StringValue) && thresholdCheck) { thresholdCheck = false; } return false; case Value.ValueType.Boolean: if (bool.Parse(sourceValue.StringValue) != bool.Parse(CheckValue.StringValue) && !thresholdCheck) { thresholdCheck = true; return true; } else if (bool.Parse(sourceValue.StringValue) == bool.Parse(CheckValue.StringValue) && thresholdCheck) { thresholdCheck = false; } return false; case Value.ValueType.Double: if (double.Parse(sourceValue.StringValue) < double.Parse(CheckValue.StringValue) && !thresholdCheck) { thresholdCheck = true; return true; } else if (double.Parse(sourceValue.StringValue) > double.Parse(CheckValue.StringValue) && thresholdCheck) { thresholdCheck = false; } return false; case Value.ValueType.String: return false; default: throw new ArgumentOutOfRangeException(); } case ConditionType.Time: return false; default: throw new ArgumentOutOfRangeException(); } } } public class Action { public enum ActionType { Passthrough, //1:1 sends source value to target Math, //runs formula to process source value first Value //sends constant value if condition met } public ActionType Type; } public string Name; public string id; public DateTime LastTrigger; public Condition condition; public Action action; public List dependencies; //triggers can depend on other triggers for combinations public Sensor source; //can be null ONLY if Type = Time public Actor target; //can be null (for dep triggers) public Trigger(string name, Condition condition, Action action, List dependencies = null, Sensor source = null, Actor target = null) { if (dependencies == null) dependencies = new List(); Name = name; id = Guid.NewGuid().ToString(); LastTrigger = DateTime.UnixEpoch; this.condition = condition; this.action = action; this.dependencies = dependencies; this.source = source; this.target = target; } } } }