aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Insights
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-16 17:05:56 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-16 17:05:56 +0300
commite47e602cd61bcca8eb7fbef40dc4aa8798510ccc (patch)
treeaed51794566ba837dcfcfb673e5d67b4ab716884 /Software/Visual_Studio/Tango.Insights
parentf809df07060dc3a27167f68027eb03bdbc89221a (diff)
downloadTango-e47e602cd61bcca8eb7fbef40dc4aa8798510ccc.tar.gz
Tango-e47e602cd61bcca8eb7fbef40dc4aa8798510ccc.zip
Working on insights...
Diffstat (limited to 'Software/Visual_Studio/Tango.Insights')
-rw-r--r--Software/Visual_Studio/Tango.Insights/InsightsFrame.cs64
-rw-r--r--Software/Visual_Studio/Tango.Insights/InsightsHelper.cs85
-rw-r--r--Software/Visual_Studio/Tango.Insights/InsightsListener.cs121
-rw-r--r--Software/Visual_Studio/Tango.Insights/InsightsManager.cs81
-rw-r--r--Software/Visual_Studio/Tango.Insights/Properties/AssemblyInfo.cs7
-rw-r--r--Software/Visual_Studio/Tango.Insights/Tango.Insights.csproj80
6 files changed, 438 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.Insights/InsightsFrame.cs b/Software/Visual_Studio/Tango.Insights/InsightsFrame.cs
new file mode 100644
index 000000000..4ea2a1c13
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Insights/InsightsFrame.cs
@@ -0,0 +1,64 @@
+using LiteDB;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Diagnostics;
+using Tango.PMR.Insights;
+using Tango.Transport.Compression;
+
+namespace Tango.Insights
+{
+ public class InsightsFrame
+ {
+ [BsonId(true)]
+ public int Id { get; set; }
+ public DateTime Time { get; set; }
+ public bool IsEmpty { get; set; }
+ public byte[] MonitorsData { get; set; }
+
+ public static InsightsFrame CreateEmpty(DateTime timeUtc)
+ {
+ InsightsFrame frame = new InsightsFrame();
+ frame.Time = timeUtc;
+ frame.IsEmpty = true;
+ frame.MonitorsData = null;
+ return frame;
+ }
+
+ public static InsightsFrame FromDiagnosticsMonitors(DiagnosticsMonitors diagnosticsMonitors, DateTime timeUtc)
+ {
+ InsightsMonitors insightsMonitors = InsightsHelper.MapMonitors(diagnosticsMonitors);
+ return FromInsightsMonitors(insightsMonitors, timeUtc);
+ }
+
+ public static InsightsFrame FromInsightsMonitors(InsightsMonitors insightsMonitors, DateTime timeUtc)
+ {
+ InsightsFrame frame = new InsightsFrame();
+ frame.Time = timeUtc;
+
+ byte[] data = insightsMonitors.ToBytes();
+ byte[] compressedData = SevenZipHelper.Compress(data);
+
+ frame.MonitorsData = compressedData;
+
+ return frame;
+ }
+
+ public InsightsMonitors ToInsightsMonitors()
+ {
+ if (IsEmpty)
+ {
+ return InsightsHelper.CreateEmptyGap();
+ }
+ else
+ {
+ var uncompressed = SevenZipHelper.Decompress(MonitorsData);
+ var insightsMonitors = InsightsMonitors.Parser.ParseFrom(uncompressed);
+ return insightsMonitors;
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Insights/InsightsHelper.cs b/Software/Visual_Studio/Tango.Insights/InsightsHelper.cs
new file mode 100644
index 000000000..202e2574d
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Insights/InsightsHelper.cs
@@ -0,0 +1,85 @@
+using Google.Protobuf.Collections;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.PMR.Diagnostics;
+using Tango.PMR.Insights;
+
+namespace Tango.Insights
+{
+ public static class InsightsHelper
+ {
+ private static List<PropertyInfo> _diagnosticsProperties;
+ private static List<PropertyInfo> _insightsProperties;
+
+ static InsightsHelper()
+ {
+ _diagnosticsProperties = new List<PropertyInfo>();
+ _insightsProperties = new List<PropertyInfo>();
+
+ foreach (var prop in typeof(DiagnosticsMonitors).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
+ _diagnosticsProperties.Add(prop);
+ }
+
+ foreach (var prop in typeof(InsightsMonitors).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+ {
+ _insightsProperties.Add(prop);
+ }
+ }
+
+ public static InsightsMonitors MapMonitors(DiagnosticsMonitors diagnosticsMonitors)
+ {
+ InsightsMonitors insightsMonitors = new InsightsMonitors();
+
+ for (int i = 0; i < _diagnosticsProperties.Count; i++)
+ {
+ if (_diagnosticsProperties[i].PropertyType == typeof(RepeatedField<double>))
+ {
+ var arr = _diagnosticsProperties[i].GetValue(diagnosticsMonitors) as RepeatedField<double>;
+
+ if (arr.Count > 0)
+ {
+ _insightsProperties[i].SetValue(insightsMonitors, arr.Average());
+ }
+ }
+ }
+
+ return insightsMonitors;
+ }
+
+ public static InsightsMonitors AverageMonitors(List<InsightsMonitors> insightsMonitorsCollection)
+ {
+ InsightsMonitors monitors = new InsightsMonitors();
+
+ foreach (var prop in _insightsProperties.Where(x => !typeof(IEnumerable).IsAssignableFrom(x.PropertyType)).ToList())
+ {
+ prop.SetValue(monitors, insightsMonitorsCollection.Average(x => (double)prop.GetValue(x)));
+ }
+
+ return monitors;
+ }
+
+ public static InsightsMonitors AverageMonitors(List<DiagnosticsMonitors> diagnosticsMonitorsCollection)
+ {
+ List<InsightsMonitors> insightsMonitorsCollection = diagnosticsMonitorsCollection.ToList().Select(x => InsightsHelper.MapMonitors(x)).ToList();
+ return AverageMonitors(insightsMonitorsCollection);
+ }
+
+ public static InsightsMonitors CreateEmptyGap()
+ {
+ InsightsMonitors monitors = new InsightsMonitors();
+
+ foreach (var prop in _insightsProperties.Where(x => !typeof(IEnumerable).IsAssignableFrom(x.PropertyType)).ToList())
+ {
+ prop.SetValue(monitors, double.NaN);
+ }
+
+ return monitors;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Insights/InsightsListener.cs b/Software/Visual_Studio/Tango.Insights/InsightsListener.cs
new file mode 100644
index 000000000..0df5b63a1
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Insights/InsightsListener.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Timers;
+using Tango.Integration.Operation;
+using Tango.PMR.Diagnostics;
+using Tango.PMR.Insights;
+
+namespace Tango.Insights
+{
+ public class InsightsListener
+ {
+ private InsightsManager _manager;
+ private IMachineOperator _operator;
+ private Timer _timer;
+ private List<DiagnosticsMonitors> _diagnosticsQueue;
+ private int _timerCount;
+ private int _deleteTicks;
+ private bool _writing;
+
+ public bool IsStarted { get; private set; }
+ public TimeSpan WriteInterval { get; set; }
+ public TimeSpan DeleteInterval { get; set; }
+ public TimeSpan MaxFramesStorage { get; set; }
+
+ public InsightsListener(InsightsManager manager, IMachineOperator machineOperator)
+ {
+ _diagnosticsQueue = new List<DiagnosticsMonitors>();
+
+ WriteInterval = TimeSpan.FromMinutes(0.1);
+ DeleteInterval = TimeSpan.FromMinutes(60);
+ MaxFramesStorage = TimeSpan.FromDays(30);
+
+ _manager = manager;
+ _operator = machineOperator;
+
+ _operator.DiagnosticsDataAvailable += _operator_DiagnosticsDataAvailable;
+ }
+
+ public InsightsListener(IMachineOperator machineOperator) : this(InsightsManager.Default, machineOperator)
+ {
+
+ }
+
+ public void Start()
+ {
+ if (!IsStarted)
+ {
+ if (_timer == null)
+ {
+ _timer = new Timer();
+ _timer.Interval = WriteInterval.TotalMilliseconds;
+ }
+
+ _writing = false;
+ _timerCount = 0;
+ _deleteTicks = (int)(DeleteInterval.TotalMilliseconds / WriteInterval.TotalMilliseconds);
+
+ _diagnosticsQueue.Clear();
+ IsStarted = true;
+ _timer.Elapsed += _timer_Elapsed;
+ _timer.Start();
+ }
+ }
+
+ public void Stop()
+ {
+ if (IsStarted)
+ {
+ _timer.Stop();
+ _diagnosticsQueue.Clear();
+ }
+ }
+
+ private void _operator_DiagnosticsDataAvailable(object sender, PMR.Diagnostics.StartDiagnosticsResponse e)
+ {
+ if (IsStarted && e.Monitors != null)
+ {
+ _diagnosticsQueue.Add(e.Monitors);
+ }
+ }
+
+ private void _timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ if (!IsStarted || _writing) return;
+
+ _writing = true;
+
+ InsightsFrame frame = null;
+
+ if (_diagnosticsQueue.Count > 0)
+ {
+ var queue = _diagnosticsQueue.ToList();
+ _diagnosticsQueue.Clear();
+
+ InsightsMonitors monitorsAvg = InsightsHelper.AverageMonitors(queue);
+ queue.Clear();
+
+ frame = InsightsFrame.FromInsightsMonitors(monitorsAvg, DateTime.UtcNow.Subtract(WriteInterval));
+ }
+ else
+ {
+ frame = InsightsFrame.CreateEmpty(DateTime.UtcNow.Subtract(WriteInterval));
+ }
+
+ _manager.InsertFrame(frame);
+
+ _timerCount++;
+
+ if (_timerCount >= _deleteTicks)
+ {
+ _timerCount = 0;
+ _manager.DeleteFrames(DateTime.UtcNow.Subtract(MaxFramesStorage));
+ }
+
+ _writing = false;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Insights/InsightsManager.cs b/Software/Visual_Studio/Tango.Insights/InsightsManager.cs
new file mode 100644
index 000000000..7597aabf4
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Insights/InsightsManager.cs
@@ -0,0 +1,81 @@
+using LiteDB;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Insights
+{
+ public class InsightsManager : IDisposable
+ {
+ private const string INSIGHTS_COLLECTION = "Insights";
+
+ private static InsightsManager _instance;
+ public static InsightsManager Default
+ {
+ get
+ {
+ if (_instance == null)
+ {
+ _instance = new InsightsManager(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Insights", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName) + ".insights"));
+ }
+
+ return _instance;
+ }
+ }
+
+ private LiteDatabase _database;
+
+ public String DatabasePath { get; private set; }
+
+ private InsightsManager(String databasePath)
+ {
+ DatabasePath = databasePath;
+ Directory.CreateDirectory(Path.GetDirectoryName(DatabasePath));
+ _database = new LiteDatabase($"Filename={DatabasePath}");
+ }
+
+ public virtual void Dispose()
+ {
+ if (_database != null)
+ {
+ try
+ {
+ _database.Dispose();
+ _database = null;
+ }
+ catch { }
+ }
+ }
+
+ ~InsightsManager()
+ {
+ Dispose();
+ }
+
+ private ILiteCollection<InsightsFrame> GetCollection()
+ {
+ return _database.GetCollection<InsightsFrame>(INSIGHTS_COLLECTION);
+ }
+
+ public virtual void InsertFrame(InsightsFrame frame)
+ {
+ var collection = GetCollection();
+ collection.Insert(frame);
+ }
+
+ public virtual List<InsightsFrame> GetFrames(DateTime startUTC, DateTime endUTC)
+ {
+ var collection = GetCollection();
+ return collection.Find(x => x.Time >= startUTC && x.Time <= endUTC).ToList();
+ }
+
+ public virtual int DeleteFrames(DateTime maxDateUTC)
+ {
+ var collection = GetCollection();
+ return collection.DeleteMany(x => x.Time < maxDateUTC);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Insights/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Tango.Insights/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..2c2308493
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Insights/Properties/AssemblyInfo.cs
@@ -0,0 +1,7 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tango - Insights Library")]
+[assembly: AssemblyVersion("2.0.12.1737")]
+[assembly: ComVisible(false)] \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Insights/Tango.Insights.csproj b/Software/Visual_Studio/Tango.Insights/Tango.Insights.csproj
new file mode 100644
index 000000000..0b9ecc641
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Insights/Tango.Insights.csproj
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{4A55C185-3F8D-41B0-8815-C15F6213A14A}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Tango.Insights</RootNamespace>
+ <AssemblyName>Tango.Insights</AssemblyName>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Versioning\GlobalVersionInfo.cs">
+ <Link>GlobalVersionInfo.cs</Link>
+ </Compile>
+ <Compile Include="InsightsHelper.cs" />
+ <Compile Include="InsightsFrame.cs" />
+ <Compile Include="InsightsListener.cs" />
+ <Compile Include="InsightsManager.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Tango.Core\Tango.Core.csproj">
+ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project>
+ <Name>Tango.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Integration\Tango.Integration.csproj">
+ <Project>{4206ac58-3b57-4699-8835-90bf6db01a61}</Project>
+ <Name>Tango.Integration</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.PMR\Tango.PMR.csproj">
+ <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project>
+ <Name>Tango.PMR</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Tango.Transport\Tango.Transport.csproj">
+ <Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
+ <Name>Tango.Transport</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Google.Protobuf">
+ <Version>3.4.1</Version>
+ </PackageReference>
+ <PackageReference Include="LiteDB">
+ <Version>5.0.4</Version>
+ </PackageReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file