You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
806 lines
31 KiB
806 lines
31 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.SqlClient;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Animation;
|
|
using DataService;
|
|
using HMIControl;
|
|
using Microsoft.Research.DynamicDataDisplay.DataSources;
|
|
using FORMS = System.Windows.Forms;
|
|
|
|
namespace CoreTest
|
|
{
|
|
public static class WindowHelper
|
|
{
|
|
//绑定到DAServer,采用递归
|
|
public static List<TagNodeHandle> BindingToServer(this DependencyObject panel, IDataServer _srv)
|
|
{
|
|
if (_srv == null) return null;
|
|
ExpressionEval eval = _srv.Eval;
|
|
List<TagNodeHandle> valueChangedList = new List<TagNodeHandle>();
|
|
var items = panel.FindTagControls();
|
|
if (items != null)
|
|
{
|
|
foreach (var element in items)
|
|
{
|
|
BindingControl(element, valueChangedList, eval);
|
|
}
|
|
}
|
|
eval.Clear();
|
|
valueChangedList.Sort();
|
|
return valueChangedList;
|
|
}
|
|
|
|
private static void BindingControl(ITagLink taglink, List<TagNodeHandle> valueChangedList, ExpressionEval eval)
|
|
{
|
|
var ctrl = taglink as UIElement;
|
|
if (ctrl == null) return;
|
|
var complex = taglink as ITagReader;
|
|
if (complex != null)
|
|
{
|
|
string txt = complex.TagReadText;
|
|
if (!string.IsNullOrEmpty(txt))
|
|
{
|
|
foreach (var v in txt.GetListFromText())
|
|
{
|
|
ITagLink tagConn = complex;
|
|
string[] strs = v.Key.Split('.');
|
|
if (strs.Length > 1)
|
|
{
|
|
for (int i = 0; i < strs.Length - 1; i++)
|
|
{
|
|
var c = tagConn as ITagReader;
|
|
if (c == null || c.Children == null) break;
|
|
foreach (var item in c.Children)
|
|
{
|
|
if (item.Node == strs[i])
|
|
{
|
|
tagConn = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var r = tagConn as ITagReader;
|
|
var key = strs[strs.Length - 1];
|
|
try
|
|
{
|
|
var action = r.SetTagReader(key, eval.Eval(v.Value));
|
|
if (action != null)
|
|
{
|
|
action();
|
|
ValueChangedEventHandler handle = (s1, e1) =>
|
|
{
|
|
ctrl.InvokeAsynchronously(action);
|
|
};
|
|
foreach (ITag tag in eval.TagList)
|
|
{
|
|
valueChangedList.Add(new TagNodeHandle(tag.ID, key, tagConn, handle));
|
|
tag.ValueChanged += handle;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
App.AddErrorLog(e);
|
|
MessageBox.Show(string.Format("设备'{0}'属性'{1}'的值'{2}'转化出错!", string.IsNullOrEmpty(r.Node) ? r.GetType().ToString() : r.Node, key, v.Value));
|
|
}
|
|
if (Attribute.IsDefined(tagConn.GetType(), typeof(StartableAttribute), false))
|
|
{
|
|
FrameworkElement element = tagConn as FrameworkElement;
|
|
element.Cursor = Cursors.UpArrow;
|
|
element.AddHandler(UIElement.MouseEnterEvent, new MouseEventHandler(element_MouseEnter));
|
|
element.AddHandler(UIElement.MouseLeaveEvent, new MouseEventHandler(element_MouseLeave));
|
|
element.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(element_MouseLeftButtonDown));
|
|
}
|
|
var hmi = tagConn as HMIControlBase;
|
|
if (hmi != null && hmi.ShowCaption && !string.IsNullOrEmpty(hmi.Caption))
|
|
{
|
|
AdornerLayer lay = AdornerLayer.GetAdornerLayer(hmi);
|
|
if (lay != null)
|
|
{
|
|
TextAdorner frame = new TextAdorner(hmi);
|
|
frame.Text = hmi.Caption;
|
|
lay.Add(frame);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var writer = taglink as ITagWriter;
|
|
if (writer != null && !string.IsNullOrEmpty(writer.TagWriteText))
|
|
{
|
|
var delgts = new List<Delegate>();
|
|
foreach (var item in writer.TagWriteText.GetListFromText())
|
|
{
|
|
try
|
|
{
|
|
if (!string.IsNullOrEmpty(item.Value))
|
|
delgts.Add(eval.WriteEval(item.Key, item.Value));
|
|
else
|
|
delgts.Add(eval.WriteEval(item.Key));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
App.AddErrorLog(e);
|
|
MessageBox.Show(string.Format("设备{0}变量{1}写入PLC公式转换失败", taglink.Node, item.Key) + "\n" + e.Message);
|
|
}
|
|
writer.SetTagWriter(delgts);
|
|
}
|
|
}
|
|
}
|
|
|
|
static AnimationTimeline animaEnter = new DoubleAnimationUsingKeyFrames
|
|
{
|
|
KeyFrames = new DoubleKeyFrameCollection { new DiscreteDoubleKeyFrame(1.05, KeyTime.FromPercent(0)) }
|
|
};
|
|
|
|
static AnimationTimeline animaLeave = new DoubleAnimationUsingKeyFrames
|
|
{
|
|
KeyFrames = new DoubleKeyFrameCollection { new DiscreteDoubleKeyFrame(1, KeyTime.FromPercent(0)) }
|
|
};
|
|
|
|
static ScaleTransform GetScaleTransform(UIElement element)
|
|
{
|
|
var group = element.RenderTransform as TransformGroup;
|
|
ScaleTransform scale = null;
|
|
if (group == null)
|
|
{
|
|
scale = new ScaleTransform();
|
|
element.RenderTransform = new TransformGroup { Children = new TransformCollection { element.RenderTransform, scale } };
|
|
}
|
|
else
|
|
{
|
|
if (group.IsFrozen)
|
|
group = group.Clone();
|
|
foreach (var transform in group.Children)
|
|
{
|
|
scale = transform as ScaleTransform;
|
|
if (scale != null)
|
|
break;
|
|
}
|
|
if (scale == null)
|
|
{
|
|
scale = new ScaleTransform();
|
|
group.Children.Add(scale);
|
|
}
|
|
element.RenderTransform = group;
|
|
}
|
|
return scale;
|
|
}
|
|
|
|
static void element_MouseEnter(object sender, MouseEventArgs e)
|
|
{
|
|
UIElement element = sender as UIElement;
|
|
//ScaleTransform scale = GetScaleTransform(element);
|
|
//scale.BeginAnimation(ScaleTransform.ScaleXProperty, animaEnter);
|
|
//scale.BeginAnimation(ScaleTransform.ScaleYProperty, animaEnter);
|
|
AdornerLayer lay = AdornerLayer.GetAdornerLayer(element);
|
|
if (lay != null)
|
|
{
|
|
FrameAdorner frame = new FrameAdorner(element);
|
|
lay.Add(frame);
|
|
}
|
|
}
|
|
|
|
static void element_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
UIElement element = sender as UIElement;
|
|
//var scale = GetScaleTransform(element);
|
|
//scale.BeginAnimation(ScaleTransform.ScaleXProperty, animaLeave);
|
|
//scale.BeginAnimation(ScaleTransform.ScaleYProperty, animaLeave);
|
|
AdornerLayer lay = AdornerLayer.GetAdornerLayer(element);
|
|
if (lay != null)
|
|
{
|
|
var adorners = lay.GetAdorners(element);
|
|
if (adorners != null)
|
|
{
|
|
FrameAdorner frame = null;
|
|
for (int i = 0; i < adorners.Length; i++)
|
|
{
|
|
frame = adorners[i] as FrameAdorner;
|
|
if (frame != null)
|
|
{
|
|
lay.Remove(frame);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
static StartDevice frm1 = null;
|
|
static void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
|
{
|
|
HMIControlBase ui = sender as HMIControlBase;
|
|
if (ui != null && !string.IsNullOrEmpty(ui.DeviceName))
|
|
{
|
|
if (frm1 != null)
|
|
frm1.Close();
|
|
frm1 = new StartDevice(ui.DeviceName, ui.PointToScreen(new Point(ui.ActualWidth / 2, ui.ActualHeight / 2)));
|
|
frm1.Show();
|
|
}
|
|
e.Handled = true;
|
|
}
|
|
|
|
static ITagLink FindElement(ITagLink tag, string key)
|
|
{
|
|
ITagLink tagConn = tag;
|
|
string[] strs = key.Split('.');
|
|
for (int i = 0; i < strs.Length; i++)
|
|
{
|
|
var c = tagConn as ITagReader;
|
|
if (c == null || c.Children == null) break;
|
|
foreach (var item in c.Children)
|
|
{
|
|
if (item.Node == strs[i])
|
|
{
|
|
tagConn = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return tagConn;
|
|
}
|
|
|
|
public static IEnumerable<DependencyObject> FindVisualChildren(this DependencyObject parent)
|
|
{
|
|
var count = VisualTreeHelper.GetChildrenCount(parent);
|
|
if (count > 0)
|
|
{
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var child = VisualTreeHelper.GetChild(parent, i);
|
|
yield return child;
|
|
|
|
var children = FindVisualChildren(child);
|
|
foreach (var item in children)
|
|
yield return item;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<T> FindChildren<T>(this DependencyObject parent) where T : class
|
|
{
|
|
var count = VisualTreeHelper.GetChildrenCount(parent);
|
|
if (count > 0)
|
|
{
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var child = VisualTreeHelper.GetChild(parent, i);
|
|
var t = child as T;
|
|
if (t != null)
|
|
yield return t;
|
|
|
|
var children = FindChildren<T>(child);
|
|
foreach (var item in children)
|
|
yield return item;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<ITagLink> FindTagControls(this DependencyObject parent)
|
|
{
|
|
var count = VisualTreeHelper.GetChildrenCount(parent);
|
|
if (count > 0)
|
|
{
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var child = VisualTreeHelper.GetChild(parent, i);
|
|
var t = child as ITagLink;
|
|
if (t != null)
|
|
yield return t;
|
|
else
|
|
{
|
|
var children = FindTagControls(child);
|
|
foreach (var item in children)
|
|
yield return item;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static LinkLine FindLine(this DependencyObject parent, string source, string target)
|
|
{
|
|
if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(target)) return null;
|
|
var controls = parent.FindTagControls(); if (controls == null) return null;
|
|
var lines = new List<LinkLine>();
|
|
Rect sourcerect = Rect.Empty;
|
|
Rect targetrect = Rect.Empty;
|
|
foreach (var ctrl in controls)
|
|
{
|
|
var element = ctrl as HMIControlBase;
|
|
if (element != null)
|
|
{
|
|
if (sourcerect == Rect.Empty && element.Caption == source)
|
|
{
|
|
sourcerect = new Rect(element.TranslatePoint(new Point(), element.Parent as UIElement), new Size(element.ActualWidth, element.ActualHeight));
|
|
}
|
|
else if (targetrect == Rect.Empty && element.Caption == target)
|
|
{
|
|
targetrect = new Rect(element.TranslatePoint(new Point(), element.Parent as UIElement), new Size(element.ActualWidth, element.ActualHeight));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var line = ctrl as LinkLine;
|
|
if (line != null)
|
|
{
|
|
if (sourcerect != Rect.Empty && targetrect != Rect.Empty)
|
|
{
|
|
if (line.OriginInfo.DesignerRect == sourcerect && line.TargetInfo.DesignerRect == targetrect)
|
|
return line;
|
|
}
|
|
else
|
|
lines.Add(line);
|
|
}
|
|
}
|
|
}
|
|
if (sourcerect == Rect.Empty || targetrect == Rect.Empty)
|
|
return null;
|
|
foreach (LinkLine line in lines)
|
|
{
|
|
if (line.OriginInfo.DesignerRect == sourcerect && line.TargetInfo.DesignerRect == targetrect)
|
|
return line;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static T HitTest<T>(this Visual hitobj, Point p)
|
|
{
|
|
var target = VisualTreeHelper.HitTest(hitobj, p).VisualHit;
|
|
while (target != null && !(target is T))
|
|
{
|
|
target = VisualTreeHelper.GetParent(target);
|
|
}
|
|
return target == null ? default(T) : (T)((object)target);
|
|
}
|
|
|
|
public static Window GetParentWindow(this DependencyObject child)
|
|
{
|
|
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
|
|
|
|
if (parentObject == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Window parent = parentObject as Window;
|
|
if (parent != null)
|
|
{
|
|
return parent;
|
|
}
|
|
else
|
|
{
|
|
return GetParentWindow(parentObject);
|
|
}
|
|
}
|
|
|
|
public static void RemoveHandles(this IDataServer srv, params List<TagNodeHandle>[] handleLists)
|
|
{
|
|
foreach (var handleList in handleLists)
|
|
{
|
|
if (handleList != null)
|
|
{
|
|
foreach (var item in handleList)
|
|
{
|
|
srv[item.TagID].ValueChanged -= item.Handle;
|
|
var element = item.Element as FrameworkElement;
|
|
if (element != null)
|
|
{
|
|
element.RemoveHandler(UIElement.MouseEnterEvent, new MouseEventHandler(element_MouseEnter));
|
|
element.RemoveHandler(UIElement.MouseLeaveEvent, new MouseEventHandler(element_MouseLeave));
|
|
element.RemoveHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(element_MouseLeftButtonDown));
|
|
}
|
|
}
|
|
handleList.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SetWindowState(this Window window)
|
|
{
|
|
Dictionary<string, Rect> dict = ConfigCache.Windows;
|
|
string name = window.DependencyObjectType.Name;
|
|
if (dict.ContainsKey(name))
|
|
{
|
|
Rect rec = dict[name];
|
|
if (rec.Width == 0 || rec.Height == 0 || double.IsInfinity(rec.Left) || double.IsInfinity(rec.Top))
|
|
{
|
|
window.WindowState = WindowState.Maximized;
|
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
|
}
|
|
else
|
|
{
|
|
window.Left = rec.Left;
|
|
window.Top = rec.Top;
|
|
window.Width = rec.Width;
|
|
window.Height = rec.Height;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ConfigCache.Windows.Add(name, new Rect());
|
|
window.WindowState = WindowState.Maximized;
|
|
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
|
}
|
|
}
|
|
|
|
public static void SaveWindowState(this Window window)
|
|
{
|
|
Dictionary<string, Rect> dict = ConfigCache.Windows;
|
|
dict[window.DependencyObjectType.Name] = window.WindowState == WindowState.Maximized ? new Rect() :
|
|
new Rect(window.Left, window.Top, window.Width, window.Height);
|
|
}
|
|
|
|
public static Window FindWindow(string name)
|
|
{
|
|
foreach (Window window in App.Current.Windows)
|
|
{
|
|
if (window.DependencyObjectType.Name == name)
|
|
{
|
|
return window;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void SetWindowPos(this Window window, int screenIndex)
|
|
{
|
|
var screens = FORMS.Screen.AllScreens;//只是测试状态,待完善
|
|
if (screenIndex < screens.Length)
|
|
{
|
|
var area = screens[screenIndex].WorkingArea;
|
|
if (window.WindowState == WindowState.Maximized)
|
|
{
|
|
window.Top = area.Top;
|
|
window.Left = area.Left;
|
|
}
|
|
else
|
|
{
|
|
window.Top += area.Top;
|
|
window.Left += area.Left;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void InvokeAsynchronously(this UIElement element, Action action)
|
|
{
|
|
if (element.Dispatcher.CheckAccess())
|
|
{
|
|
action();
|
|
}
|
|
else
|
|
element.Dispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.Normal);
|
|
}
|
|
|
|
public static void GetWorkInfo(DateTime current, out DateTime start, out DateTime end, out string team)
|
|
{
|
|
float[] startarray = new float[3] { App.Server["START_1"].Value.Single, App.Server["START_2"].Value.Single, App.Server["START_3"].Value.Single };
|
|
float[] endarray = new float[3] { App.Server["END_1"].Value.Single, App.Server["END_2"].Value.Single, App.Server["END_3"].Value.Single };
|
|
double hour = current.Hour + current.Minute / 60.0;
|
|
//Array.Sort(startarray);
|
|
DateTime today = current.Date;
|
|
for (int i = 0; i < startarray.Length; i++)
|
|
{
|
|
if (startarray[i] == endarray[i]) continue;
|
|
if (hour >= startarray[i] && hour <= endarray[i])
|
|
{
|
|
start = today.AddHours(startarray[i]);
|
|
end = today.AddHours(endarray[i]);
|
|
team = i.ToString();
|
|
return;
|
|
}
|
|
else if (startarray[i] >= endarray[i] && hour >= startarray[i])
|
|
{
|
|
start = today.AddHours(startarray[i]);
|
|
end = today.AddDays(1).AddHours(endarray[i]);
|
|
team = i.ToString();
|
|
return;
|
|
}
|
|
else if (startarray[i] >= endarray[i] && hour <= endarray[i])
|
|
{
|
|
start = today.AddDays(-1).AddHours(startarray[i]);
|
|
end = today.AddHours(endarray[i]);
|
|
team = i.ToString();
|
|
return;
|
|
}
|
|
}
|
|
start = current.AddHours(-8);
|
|
end = current;
|
|
team = null;
|
|
}
|
|
|
|
//startTime/endTime:班次上/下班时间 starthour/endhour:阶段起始/结束时间 start/end:本班次阶段区间
|
|
public static void GetTimeRange(DateTime startTime, DateTime endTime, float starthour, float endhour, out DateTime start, out DateTime end)
|
|
{
|
|
if (starthour == endhour)
|
|
{
|
|
start = end = DateTime.MinValue;
|
|
return;
|
|
}
|
|
DateTime startdate = startTime.Date;
|
|
DateTime enddate = endTime.Date;
|
|
double hstart = startTime.Hour + startTime.Minute / 60.0 + startTime.Second / 60.0;
|
|
double hend = endTime.Hour + endTime.Minute / 60.0 + endTime.Second / 60.0;
|
|
if (startdate == enddate)
|
|
{
|
|
if (endhour > starthour)
|
|
{
|
|
start = starthour > hstart ? startdate.AddHours(starthour) : startTime;
|
|
end = endhour < hend ? startdate.AddHours(endhour) : endTime;
|
|
}
|
|
else
|
|
{
|
|
if (endhour > hstart)
|
|
{
|
|
start = startTime;
|
|
end = endhour > hend ? endTime : startdate.AddHours(endhour);
|
|
}
|
|
else if (starthour < hend)
|
|
{
|
|
end = endTime;
|
|
start = starthour > hstart ? startdate.AddHours(starthour) : startTime;
|
|
}
|
|
else
|
|
{
|
|
start = end = DateTime.MinValue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (endhour > starthour)
|
|
{
|
|
if (endhour > hstart)
|
|
{
|
|
start = starthour > hstart ? startdate.AddHours(starthour) : startTime;
|
|
end = startdate.AddHours(endhour);
|
|
}
|
|
else if (starthour < hend)
|
|
{
|
|
end = endhour < hend ? enddate.AddHours(endhour) : endTime;
|
|
start = enddate.AddHours(starthour);
|
|
}
|
|
else
|
|
{
|
|
start = end = DateTime.MinValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
start = starthour > hstart ? startdate.AddHours(starthour) : startTime;
|
|
end = endhour < hend ? enddate.AddHours(endhour) : endTime;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SetSourceMapping(this QueueListSource<HistoryData> source, ITag currentTag)
|
|
{
|
|
if (currentTag != null)
|
|
{
|
|
switch (currentTag.Address.VarType)
|
|
{
|
|
case DataType.BOOL:
|
|
source.SetYMapping(Y => Y.Value.Boolean ? 1 : 0);
|
|
break;
|
|
case DataType.BYTE:
|
|
source.SetYMapping(Y => Y.Value.Byte);
|
|
break;
|
|
case DataType.WORD:
|
|
case DataType.SHORT:
|
|
source.SetYMapping(Y => Y.Value.Int16);
|
|
break;
|
|
case DataType.TIME:
|
|
case DataType.INT:
|
|
source.SetYMapping(Y => Y.Value.Int32);
|
|
break;
|
|
case DataType.FLOAT:
|
|
source.SetYMapping(Y => Y.Value.Single);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void SetSourceMapping(this ObservableDataSource<HistoryData> source, ITag currentTag)
|
|
{
|
|
if (currentTag != null)
|
|
{
|
|
switch (currentTag.Address.VarType)
|
|
{
|
|
case DataType.BOOL:
|
|
source.SetYMapping(Y => Y.Value.Boolean ? 1 : 0);
|
|
break;
|
|
case DataType.BYTE:
|
|
source.SetYMapping(Y => Y.Value.Byte);
|
|
break;
|
|
case DataType.WORD:
|
|
case DataType.SHORT:
|
|
source.SetYMapping(Y => Y.Value.Int16);
|
|
break;
|
|
case DataType.TIME:
|
|
case DataType.INT:
|
|
source.SetYMapping(Y => Y.Value.Int32);
|
|
break;
|
|
case DataType.FLOAT:
|
|
source.SetYMapping(Y => Y.Value.Single);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TagNodeHandle : IComparable<TagNodeHandle>
|
|
{
|
|
short _tagID;
|
|
public short TagID
|
|
{
|
|
get
|
|
{
|
|
return _tagID;
|
|
}
|
|
}
|
|
|
|
string _key;
|
|
public string Key
|
|
{
|
|
get
|
|
{
|
|
return _key;
|
|
}
|
|
}
|
|
|
|
ITagLink _element;
|
|
public ITagLink Element
|
|
{
|
|
get
|
|
{
|
|
return _element;
|
|
}
|
|
}
|
|
|
|
ValueChangedEventHandler _handle;
|
|
public ValueChangedEventHandler Handle
|
|
{
|
|
get
|
|
{
|
|
return _handle;
|
|
}
|
|
}
|
|
|
|
public TagNodeHandle(short tag, string key, ITagLink element, ValueChangedEventHandler handle)
|
|
{
|
|
_tagID = tag;
|
|
_key = key;
|
|
_element = element;
|
|
_handle = handle;
|
|
}
|
|
|
|
public int CompareTo(TagNodeHandle other)
|
|
{
|
|
int comp = _tagID.CompareTo(other._tagID);
|
|
return comp == 0 ? _key.CompareTo(other._key) : comp;
|
|
}
|
|
}
|
|
|
|
public static class Extension
|
|
{
|
|
public static string GetNullableString(this SqlDataReader dataReader, int index)
|
|
{
|
|
var svr = dataReader.GetSqlString(index);
|
|
return svr.IsNull ? null : svr.Value;
|
|
}
|
|
|
|
public static string GetNullableString(this DateTime? time)
|
|
{
|
|
return time.HasValue ? "'" + time.ToString() + "'" : "NULL";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回指定变量最接近指定时间的值
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="time">时间</param>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public static int GetInt(this IEnumerable<HistoryData> list, DateTime time, short id)
|
|
{
|
|
var data = (from raw in list where raw.ID == id && raw.TimeStamp <= time && raw.Value.Int32 > 0 select raw.Value.Int32).LastOrDefault();
|
|
if (data == 0) data = (from raw in list where raw.ID == id && raw.TimeStamp >= time && raw.Value.Int32 > 0 select raw.Value.Int32).FirstOrDefault();
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回变量最接近指定时间的值
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="time">时间</param>
|
|
/// <returns></returns>
|
|
public static int GetInt(this IEnumerable<HistoryData> list, DateTime time)
|
|
{
|
|
var data = (from raw in list where raw.TimeStamp <= time && raw.Value.Int32 > 0 select raw.Value.Int32).LastOrDefault();
|
|
if (data == 0) data = (from raw in list where raw.TimeStamp >= time && raw.Value.Int32 > 0 select raw.Value.Int32).FirstOrDefault();
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回在开始时间和结束时间范围内变量的变化值
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="start">开始时间</param>
|
|
/// <param name="end">结束时间</param>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public static int GetInt(this IEnumerable<HistoryData> list, DateTime start, DateTime end, short id)
|
|
{
|
|
return GetInt(list, end, id) - GetInt(list, start, id);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回指定变量最接近指定时间的值
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="time">时间</param>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public static float GetFloat(this IEnumerable<HistoryData> list, DateTime time, short id)
|
|
{
|
|
var data = (from raw in list where raw.ID == id && raw.TimeStamp <= time && raw.Value.Single > 0 select raw.Value.Single).LastOrDefault();
|
|
if (data == 0) data = (from raw in list where raw.ID == id && raw.TimeStamp >= time && raw.Value.Single > 0 select raw.Value.Single).FirstOrDefault();
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回变量最接近指定时间的值
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="time">时间</param>
|
|
/// <returns></returns>
|
|
public static float GetFloat(this IEnumerable<HistoryData> list, DateTime time)
|
|
{
|
|
var data = (from raw in list where raw.TimeStamp <= time && raw.Value.Single > 0 select raw.Value.Single).LastOrDefault();
|
|
if (data == 0) data = (from raw in list where raw.TimeStamp >= time && raw.Value.Single > 0 select raw.Value.Single).FirstOrDefault();
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回在开始时间和结束时间范围内变量的变化值
|
|
/// </summary>
|
|
/// <param name="list"></param>
|
|
/// <param name="start">开始时间</param>
|
|
/// <param name="end">结束时间</param>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public static float GetFloat(this IEnumerable<HistoryData> list, DateTime start, DateTime end, short id)
|
|
{
|
|
return GetFloat(list, end, id) - GetFloat(list, start, id);
|
|
}
|
|
|
|
public static float GetFloat2(this List<HistoryData> list, DateTime start, DateTime end, short id)
|
|
{
|
|
float result = 0;
|
|
var data = (from raw in list where raw.TimeStamp >= start && raw.TimeStamp <= end && raw.ID == id && raw.Value.Single >= 0 select raw.Value.Single).ToList();
|
|
if (data.Count > 0)
|
|
{
|
|
List<int> li = new List<int>();
|
|
li.Add(0);
|
|
for (int i = 0; i < data.Count - 1; i++)
|
|
{
|
|
if (data[i] > data[i + 1] && i > 0)
|
|
{
|
|
li.Add(i);
|
|
}
|
|
}
|
|
li.Add(data.Count - 1);
|
|
for (int i = 1; i < li.Count; i++)
|
|
{
|
|
result += data[li[i]] - data[li[i - 1] + 1];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|