222 lines
5.8 KiB
C#
222 lines
5.8 KiB
C#
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
|
|
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<Trigger> 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<Trigger> dependencies = null, Sensor source = null, Actor target = null)
|
|
{
|
|
if (dependencies == null)
|
|
dependencies = new List<Trigger>();
|
|
Name = name;
|
|
id = Guid.NewGuid().ToString();
|
|
LastTrigger = DateTime.UnixEpoch;
|
|
this.condition = condition;
|
|
this.action = action;
|
|
this.dependencies = dependencies;
|
|
this.source = source;
|
|
this.target = target;
|
|
}
|
|
}
|
|
}
|
|
} |