using DevExpress.XtraEditors.Controls;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.Collections.Specialized;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
|
namespace TProduct.WinFrmUI.TPump
|
{
|
class FeatTestRealTimeGenerator
|
{
|
const int InitialDataPointsCount = 10000;
|
const int DataGenerationIntervalMilliseconds = 15;
|
|
readonly FeatTestRealTimeCollection dataSource = new FeatTestRealTimeCollection();
|
readonly Random random = new Random(1);
|
readonly List<FeatTestRealTimeItem> buffer = new List<FeatTestRealTimeItem>();
|
readonly object sync = new object();
|
int counter;
|
double yPower = 0;
|
double yFlow = 0;
|
double yInletPress = 0;
|
double yOutletPress = 0;
|
bool generatingEnabled = false;
|
Thread generatingThread;
|
|
internal FeatTestRealTimeCollection DataSource
|
{
|
get { return dataSource; }
|
}
|
|
FeatTestRealTimeItem CreatePoint(DateTime timeStamp)
|
{
|
counter++;
|
double arg = timeStamp.ToOADate();
|
arg = arg * 250000d;
|
if (counter % random.Next(300, 500) == 0)
|
yPower += random.Next(10, 20) * Math.Sign(random.NextDouble() - 0.5);
|
if (yPower < -30)
|
yPower += 10;
|
if (yPower > 30)
|
yPower -= 10;
|
double indication1 = 5 * Math.Sin(5d / 2d * Math.Cos(arg)) + 100 + (random.NextDouble() - 0.5) * 5 + yPower;
|
|
if (counter % random.Next(100, 500) == 0)
|
yFlow += random.Next(10, 20) * Math.Sign(random.NextDouble() - 0.5);
|
if (yFlow < -30)
|
yFlow += 10;
|
if (yFlow > 30)
|
yFlow -= 10;
|
double indication3 = 10 * (Math.Sin(arg) + Math.Sin(arg / 1.2d) + Math.Sin(arg / 1.5d)) + 100 + random.NextDouble() * 12 + yFlow;
|
|
if (counter % random.Next(300, 400) == 0)
|
yInletPress += random.Next(10, 20) * Math.Sign(random.NextDouble() - 0.5);
|
if (yInletPress < -30)
|
yInletPress += 10;
|
if (yInletPress > 30)
|
yInletPress -= 10;
|
double indication5 = 15 * Math.Cos(Math.Tan(arg + random.NextDouble() / 10)) + 500 + random.NextDouble() * 15 + yInletPress;
|
if (counter % random.Next(400, 1000) == 0)
|
yOutletPress += random.Next(10, 20) * Math.Sign(random.NextDouble() - 0.5);
|
if (yOutletPress < -30)
|
yOutletPress += 10;
|
if (yOutletPress > 30)
|
yOutletPress -= 10;
|
double indication6 = 20 * Math.Sin(Math.Tan(arg + 1)) + 450 + random.NextDouble() * 9 + yOutletPress;
|
|
|
return new FeatTestRealTimeItem(timeStamp, indication1, indication3, indication5, indication6 );
|
}
|
void AddPoint(DateTime timeStamp)
|
{
|
FeatTestRealTimeItem point = CreatePoint(timeStamp);
|
lock (sync)
|
{
|
buffer.Add(point);
|
}
|
}
|
void GeneratingLoop()
|
{
|
DateTime timeStamp = DateTime.Now;
|
while (generatingEnabled)
|
{
|
DateTime newTimeStamp = timeStamp.AddMilliseconds(DataGenerationIntervalMilliseconds);
|
TimeSpan span = newTimeStamp - DateTime.Now;
|
if (span.Ticks > 0)
|
Thread.Sleep((int)span.TotalMilliseconds);
|
timeStamp = newTimeStamp;
|
AddPoint(timeStamp);
|
}
|
}
|
|
internal void GenerateInitialData()
|
{
|
DateTime baseTimeStamp = DateTime.Now.AddMilliseconds(-InitialDataPointsCount * DataGenerationIntervalMilliseconds);
|
DateTime argument = baseTimeStamp;
|
for (int i = 0; i < InitialDataPointsCount - 1; i++)
|
{
|
argument = argument.AddMilliseconds(DataGenerationIntervalMilliseconds);
|
FeatTestRealTimeItem point = CreatePoint(argument);
|
dataSource.Add(point);
|
}
|
}
|
internal void UpdateDataSource()
|
{
|
lock (sync)
|
{
|
dataSource.AddRange(buffer);
|
if (dataSource.Count > InitialDataPointsCount)
|
dataSource.RemoveRangeAt(0, buffer.Count);
|
buffer.Clear();
|
}
|
}
|
internal void Start()
|
{
|
if (generatingThread == null)
|
generatingThread = new Thread(new ThreadStart(GeneratingLoop));
|
generatingEnabled = true;
|
generatingThread.Start();
|
}
|
internal void Stop()
|
{
|
generatingEnabled = false;
|
if (generatingThread != null)
|
generatingThread.Join();
|
generatingThread = null;
|
}
|
}
|
|
class FeatTestRealTimeCollection : ObservableCollection<FeatTestRealTimeItem>
|
{
|
internal void AddRange(List<FeatTestRealTimeItem> items)
|
{
|
foreach (FeatTestRealTimeItem item in items)
|
Items.Add(item);
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, items, Items.Count - items.Count));
|
}
|
internal void RemoveRangeAt(int startingIndex, int count)
|
{
|
var removedItems = new List<FeatTestRealTimeItem>(count);
|
for (int i = 0; i < count; i++)
|
{
|
removedItems.Add(Items[startingIndex]);
|
Items.RemoveAt(startingIndex);
|
}
|
if (count > 0)
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removedItems, startingIndex));
|
}
|
}
|
|
public class FeatTestRealTimeItem
|
{
|
public DateTime TimeStamp { get; set; }
|
public double Power { get; set; }
|
public double Flow { get; set; }
|
public double InletPress { get; set; }
|
public double OutletPress { get; set; }
|
internal FeatTestRealTimeItem() { }
|
internal FeatTestRealTimeItem(
|
DateTime timeStamp,
|
double power,
|
double flow,
|
double inlet_press,
|
double outlet_press)
|
{
|
this.TimeStamp = timeStamp;
|
this.Power = power;
|
this.Flow = flow;
|
this.InletPress = inlet_press;
|
this.OutletPress = outlet_press;
|
}
|
}
|
|
|
}
|