aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben Shabat <roy.mail.net@gmail.com>2025-08-30 22:05:03 +0300
committerRoy Ben Shabat <roy.mail.net@gmail.com>2025-08-30 22:05:03 +0300
commita1d55aa060450b0a16b597794686b2aa41eea259 (patch)
tree62dfd7829b81335103a3c2d1d17c99d8408a5e54 /Software/Visual_Studio
parentd9d5b0161efbce3f0d44e890b435883f49df2963 (diff)
downloadTango-a1d55aa060450b0a16b597794686b2aa41eea259.tar.gz
Tango-a1d55aa060450b0a16b597794686b2aa41eea259.zip
PPC Telemetry First Integration.
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs3
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/IMachineProvider.cs3
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj4
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/ITelemetryProvider.cs13
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/TelemetrySettings.cs61
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/App.config42
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj177
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/Telemetry/DefaultTelemetryProvider.cs209
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs4
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/packages.config74
-rw-r--r--Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs1
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs49
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/Destinations/TelemetryAzureHubBatchDestination.cs208
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSource.cs2
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSourceConfig.cs2
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryJobStatusSource.cs126
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/Tango.Telemetry.csproj1
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/TelemetryLiteDBStorageManager.cs18
-rw-r--r--Software/Visual_Studio/Tango.Telemetry/TelemetryPublisherConfiguration.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs54
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj10
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Web.config8
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/packages.config3
23 files changed, 956 insertions, 118 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs
index 695d71b4b..872523bd0 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs
@@ -46,6 +46,7 @@ namespace Tango.PPC.Common.Connection
/// Occurs when the machine has disconnected.
/// </summary>
public event EventHandler MachineDisconnected;
+ public event EventHandler<Machine> Initialized;
private bool _isConnected;
/// <summary>
@@ -345,6 +346,8 @@ namespace Tango.PPC.Common.Connection
MachineOperator.JobRunsLogger.SetDefaultMachine(Machine);
+ Initialized?.Invoke(this, Machine);
+
ConnectToMachine();
}
else
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/IMachineProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/IMachineProvider.cs
index 774fa7c9e..52ab2620b 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/IMachineProvider.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/IMachineProvider.cs
@@ -25,6 +25,9 @@ namespace Tango.PPC.Common.Connection
/// </summary>
event EventHandler MachineDisconnected;
+
+ event EventHandler<Machine> Initialized;
+
/// <summary>
/// Gets a value indicating whether the machine is currently connected.
/// </summary>
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
index 7c20d08f5..c98a47e9a 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj
@@ -273,6 +273,8 @@
<Compile Include="Synchronization\SynchronizationStatusChangedEventArgs.cs" />
<Compile Include="SystemInfo\DefaultSystemInfoService.cs" />
<Compile Include="SystemInfo\ISystemInfoService.cs" />
+ <Compile Include="Telemetry\ITelemetryProvider.cs" />
+ <Compile Include="Telemetry\TelemetrySettings.cs" />
<Compile Include="ThreadLoading\IThreadLoadingService.cs" />
<Compile Include="UpdatePackages\DefaultPackageRunner.cs" />
<Compile Include="UpdatePackages\IPackageRunner.cs" />
@@ -680,7 +682,7 @@
</Target>
<ProjectExtensions>
<VisualStudio>
- <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
+ <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
</VisualStudio>
</ProjectExtensions>
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/ITelemetryProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/ITelemetryProvider.cs
new file mode 100644
index 000000000..529775d0e
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/ITelemetryProvider.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.PPC.Common.Telemetry
+{
+ public interface ITelemetryProvider
+ {
+ TelemetrySettings Settings { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/TelemetrySettings.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/TelemetrySettings.cs
new file mode 100644
index 000000000..7acf7e197
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Telemetry/TelemetrySettings.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Logging;
+using Tango.Settings;
+
+namespace Tango.PPC.Common.Telemetry
+{
+ public class TelemetrySettings : SettingsBase
+ {
+ public bool Enable { get; set; } = true;
+
+ public bool EnableIoTHub { get; set; } = true;
+ public bool EnableMqtt { get; set; } = false;
+
+ public String IoTHubConnectionString { get; set; } = "HostName=iot-twine-dev-weu.azure-devices.net;DeviceId=telemetry-dev-01;SharedAccessKey=cZhCMhiVL+TF7p13fpX+lFmyxoy8ZqCkbxUwumWw18Q=";
+
+ /// <summary>
+ /// Interval for checking and reprocessing failed/pending telemetry from local storage.
+ /// </summary>
+ public TimeSpan PendingStorageCheckInterval { get; set; } = TimeSpan.FromMinutes(1);
+
+ /// <summary>
+ /// Frequency at which historical sources are polled to request backlogged or missed telemetry.
+ /// </summary>
+ public TimeSpan HistorySourcesRequestInterval { get; set; } = TimeSpan.FromMinutes(1);
+
+ /// <summary>
+ /// Whether exponential backoff should be applied to retry logic per destination.
+ /// </summary>
+ public bool EnableBackoff { get; set; } = false;
+
+ /// <summary>
+ /// The maximum amount of time to delay retries during exponential backoff.
+ /// </summary>
+ public TimeSpan MaxExponentialBackoff { get; set; } = TimeSpan.FromHours(1);
+
+ /// <summary>
+ /// Gets or sets the interval at which the published telemetry cache cleanup process should occur.
+ /// This defines how frequently old published telemetry entries are eligible for pruning,
+ /// based on their publication timestamp.
+ /// </summary>
+ public TimeSpan PublishedTelemetriesCacheCleanupInterval { get; set; } = TimeSpan.FromHours(1);
+
+ public bool SendDiagnostics { get; set; } = true;
+ public TimeSpan DiagnosticsSamplingInterval { get; set; } = TimeSpan.FromSeconds(60);
+ public bool SendEvents { get; set; } = true;
+ public bool SendJobRuns { get; set; } = true;
+ public bool SendJobRunsHistory { get; set; } = true;
+ public bool SendJobStatus { get; set; } = true;
+ public bool SendLogs { get; set; } = true;
+ public bool SendMachineStatus { get; set; } = true;
+ public bool SendMachineUpdates { get; set; } = true;
+ public bool SendMachineUpdatesHistory { get; set; } = true;
+ public bool SendWires { get; set; } = true;
+
+ public HashSet<LogCategory> LogCategories { get; set; } = new HashSet<LogCategory>() { LogCategory.Critical, LogCategory.Error, LogCategory.Warning };
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config
index 4d7554231..53a599bee 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/App.config
@@ -84,7 +84,7 @@
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
+ <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
@@ -96,6 +96,46 @@
</dependentAssembly>
+ <dependentAssembly>
+
+ <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+
+ <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
+
+ </dependentAssembly>
+
+ <dependentAssembly>
+
+ <assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+
+ <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
+
+ </dependentAssembly>
+
+ <dependentAssembly>
+
+ <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+
+ <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
+
+ </dependentAssembly>
+
+ <dependentAssembly>
+
+ <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+
+ <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
+
+ </dependentAssembly>
+
+ <dependentAssembly>
+
+ <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
+
+ <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
+
+ </dependentAssembly>
+
</assemblyBinding>
</runtime>
<entityFramework>
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj
index 31c46b296..99a7e7c75 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj
@@ -98,6 +98,24 @@
<Reference Include="ControlzEx, Version=3.0.2.4, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll</HintPath>
</Reference>
+ <Reference Include="DotNetty.Buffers, Version=0.4.6.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\DotNetty.Buffers.0.4.6\lib\net45\DotNetty.Buffers.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetty.Codecs, Version=0.4.6.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\DotNetty.Codecs.0.4.6\lib\net45\DotNetty.Codecs.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetty.Codecs.Mqtt, Version=0.4.6.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\DotNetty.Codecs.Mqtt.0.4.6\lib\net45\DotNetty.Codecs.Mqtt.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetty.Common, Version=0.4.6.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\DotNetty.Common.0.4.6\lib\net45\DotNetty.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetty.Handlers, Version=0.4.6.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\DotNetty.Handlers.0.4.6\lib\net45\DotNetty.Handlers.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetty.Transport, Version=0.4.6.0, Culture=neutral, PublicKeyToken=bc13ca065fa06c29, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\DotNetty.Transport.0.4.6\lib\net45\DotNetty.Transport.dll</HintPath>
+ </Reference>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
@@ -110,14 +128,84 @@
<Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
+ <Reference Include="Microsoft.Azure.Amqp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Azure.Amqp.2.0.6\lib\net45\Microsoft.Azure.Amqp.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Azure.Devices.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Azure.Devices.Client.1.6.0\lib\net45\Microsoft.Azure.Devices.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Azure.Devices.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Azure.Devices.Shared.1.3.0\lib\net45\Microsoft.Azure.Devices.Shared.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Data.Edm.5.6.4\lib\net40\Microsoft.Data.Edm.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Data.OData.5.6.4\lib\net40\Microsoft.Data.OData.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.4\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Logging, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Logging.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
<Reference Include="Microsoft.WindowsAPICodePack, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.WindowsAPICodePack-Core.1.1.0.0\lib\Microsoft.WindowsAPICodePack.dll</HintPath>
</Reference>
+ <Reference Include="Microsoft.WindowsAzure.Storage, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\WindowsAzure.Storage.7.0.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
+ </Reference>
+ <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\PCLCrypto.2.0.147\lib\net45\PCLCrypto.dll</HintPath>
+ </Reference>
+ <Reference Include="PInvoke.BCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\PInvoke.BCrypt.0.3.2\lib\net40\PInvoke.BCrypt.dll</HintPath>
+ </Reference>
+ <Reference Include="PInvoke.Kernel32, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\PInvoke.Kernel32.0.3.2\lib\net40\PInvoke.Kernel32.dll</HintPath>
+ </Reference>
+ <Reference Include="PInvoke.NCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\PInvoke.NCrypt.0.3.2\lib\net40\PInvoke.NCrypt.dll</HintPath>
+ </Reference>
+ <Reference Include="PInvoke.Windows.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath>
+ </Reference>
<Reference Include="SimpleValidator, Version=0.6.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimpleValidator.0.6.1.0\lib\net40\SimpleValidator.dll</HintPath>
</Reference>
<Reference Include="System" />
+ <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.SQLite, Version=1.0.108.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Data.SQLite.Core.1.0.108.0\lib\net46\System.Data.SQLite.dll</HintPath>
@@ -131,7 +219,78 @@
<HintPath>..\..\packages\System.Data.SQLite.Linq.1.0.108.0\lib\net46\System.Data.SQLite.Linq.dll</HintPath>
<Private>True</Private>
</Reference>
+ <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
+ </Reference>
<Reference Include="System.Drawing" />
+ <Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.IO.Compression.FileSystem" />
+ <Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Spatial.5.6.4\lib\net40\System.Spatial.dll</HintPath>
+ </Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Expression.Blend.Sdk.1.0.2\lib\net45\System.Windows.Interactivity.dll</HintPath>
@@ -141,10 +300,17 @@
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
+ <Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
+ <Private>True</Private>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="Validation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath>
+ </Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
@@ -288,6 +454,7 @@
<Compile Include="PPCApplication\DefaultPPCApplicationManager.cs" />
<Compile Include="Printing\DefaultPrintingManager.cs" />
<Compile Include="RemoteActions\DefaultRemoteActionsService.cs" />
+ <Compile Include="Telemetry\DefaultTelemetryProvider.cs" />
<Compile Include="Threading\DefaultDispatcherProvider.cs" />
<Compile Include="ThreadLoading\DefaultThreadLoadingService.cs" />
<Compile Include="ViewModelLocator.cs" />
@@ -707,7 +874,9 @@
</None>
</ItemGroup>
<ItemGroup>
- <None Include="App.config" />
+ <None Include="App.config">
+ <SubType>Designer</SubType>
+ </None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SideChains\RealTimeGraphX-master\RealTimeGraphX.WPF\RealTimeGraphX.WPF.csproj">
@@ -778,6 +947,10 @@
<Project>{e1e66ed9-597d-45fa-8048-de90a6930484}</Project>
<Name>Tango.SQLExaminer</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\Tango.Telemetry\Tango.Telemetry.csproj">
+ <Project>{af593663-d4e9-4a14-a3f2-fea57f30e9e6}</Project>
+ <Name>Tango.Telemetry</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.TFS\Tango.TFS.csproj">
<Project>{998f8471-dc1b-41b6-9d96-354e1b4e7a32}</Project>
<Name>Tango.TFS</Name>
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Telemetry/DefaultTelemetryProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Telemetry/DefaultTelemetryProvider.cs
new file mode 100644
index 000000000..04837bb38
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Telemetry/DefaultTelemetryProvider.cs
@@ -0,0 +1,209 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Tango.BL;
+using Tango.BL.Entities;
+using Tango.Core.DI;
+using Tango.PPC.Common;
+using Tango.PPC.Common.Application;
+using Tango.PPC.Common.Connection;
+using Tango.PPC.Common.Telemetry;
+using Tango.PPC.Common.Web;
+using Tango.Settings;
+using Tango.Telemetry;
+using Tango.Telemetry.Destinations;
+using Tango.Telemetry.Helpers;
+using Tango.Telemetry.Sources;
+
+namespace Tango.PPC.UI.Telemetry
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultTelemetryProvider : ITelemetryProvider, ITelemetryCheckpointsRecoveryClient
+ {
+ private PPCWebClient _webClient;
+ private Machine _machine;
+ private IMachineProvider _machineProvider;
+ private PPCSettings _ppcSettings;
+
+ public TelemetrySettings Settings { get; set; }
+
+ public ITelemetryPublisher TelemetryPublisher { get; set; }
+
+ public DefaultTelemetryProvider(IPPCApplicationManager applicationManager, IMachineProvider machineProvider, PPCWebClient webClient)
+ {
+ Settings = SettingsManager.Default.GetOrCreate<TelemetrySettings>();
+ applicationManager.ApplicationReady += ApplicationManager_ApplicationReady;
+ _webClient = webClient;
+ _machineProvider = machineProvider;
+ }
+
+ private void ApplicationManager_ApplicationReady(object sender, EventArgs e)
+ {
+ try
+ {
+ if (Settings.Enable)
+ {
+ Init();
+ }
+ }
+ catch { }
+ }
+
+ private void Init()
+ {
+ if (_machineProvider.Machine == null) return;
+
+ _machine = _machineProvider.Machine;
+
+ _ppcSettings = SettingsManager.Default.GetOrCreate<PPCSettings>();
+
+ using (ObservablesContext db = ObservablesContext.CreateDefault())
+ {
+ var site = db.Sites.FirstOrDefault(x => x.Guid == _machine.SiteGuid);
+
+ TelemetryPublisher = new TelemetryPublisher(new TelemetryPublisherConfiguration()
+ {
+ Environment = _ppcSettings.DeploymentSlot.ToString(),
+ Organization = _machine.Organization.Name,
+ Site = site?.Name,
+ SerialNumber = _machine.SerialNumber,
+ MachineType = _machine.Type,
+ EnableBackoff = Settings.EnableBackoff,
+ HistorySourcesRequestInterval = Settings.HistorySourcesRequestInterval,
+ MaxExponentialBackoff = Settings.MaxExponentialBackoff,
+ PendingStorageCheckInterval = Settings.PendingStorageCheckInterval,
+ }, this);
+
+ (TelemetryPublisher.StorageManager as TelemetryLiteDBStorageManager).EnableCheckPointsRecovery = true;
+ (TelemetryPublisher.StorageManager as TelemetryLiteDBStorageManager).EnforceCheckpointsRecovery = true;
+ }
+
+ InternetConnectivity.EnsureStarted();
+
+ Task.Factory.StartNew(async () =>
+ {
+ while (!InternetConnectivity.IsInternetAvailable())
+ {
+ Thread.Sleep(5000);
+ }
+
+ if (!_webClient.IsAuthenticated)
+ {
+ await _webClient.Login(new LoginRequest() { Mode = LoginMode.Machine, SerialNumber = _machine.SerialNumber, MachineGuid = _machine.Guid });
+ }
+
+ var response = await _webClient.GetTelemetryDeviceConnection(new TelemetryDeviceRegistrationRequest());
+ Settings.IoTHubConnectionString = response.ConnectionString;
+ Settings.Save();
+
+ if (Settings.EnableIoTHub)
+ {
+ TelemetryPublisher.RegisterDestination(new TelemetryAzureHubDestination(Settings.IoTHubConnectionString));
+ }
+
+ if (Settings.EnableMqtt)
+ {
+ TelemetryPublisher.RegisterDestination(new TelemetryMqttDestination($"Twine {_machine.SerialNumber}"));
+ }
+
+ if (Settings.SendDiagnostics)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryDiagnosticsStreamingSource(_machineProvider.MachineOperator)
+ {
+ Config = new TelemetryDiagnosticsStreamingSourceConfig()
+ {
+ DiagnosticsSamplingInterval = Settings.DiagnosticsSamplingInterval,
+ }
+ });
+ }
+
+ if (Settings.SendEvents)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryEventsStreamingSource(_machineProvider.MachineOperator));
+ }
+
+ if (Settings.SendJobRuns)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryJobRunsStreamingSource(_machineProvider.MachineOperator));
+ }
+
+ if (Settings.SendJobRunsHistory)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryJobRunsHistorySource() { Config = new TelemetryJobRunsHistorySourceConfig() { MaxJobRunsPerRequest = 10 } });
+ }
+
+ if (Settings.SendJobStatus)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryJobStatusSource(_machineProvider.MachineOperator));
+ }
+
+ if (Settings.SendLogs)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryLogsStreamingSource(_machineProvider.MachineOperator)
+ {
+ Config = new TelemetryLogsStreamingSourceConfig()
+ {
+ Categories = Settings.LogCategories
+ }
+ });
+ }
+
+ if (Settings.SendMachineStatus)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryMachineStatusStreamingSource(_machineProvider.MachineOperator));
+ }
+
+ if (Settings.SendMachineUpdates)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryMachineUpdatesStreamingSource());
+ }
+
+ if (Settings.SendMachineUpdatesHistory)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryMachineUpdatesHistorySource());
+ }
+
+ if (Settings.SendWires)
+ {
+ TelemetryPublisher.RegisterSource(new TelemetryWireStreamingSource(_machineProvider.MachineOperator));
+ }
+
+ await TelemetryPublisher.Start();
+ });
+ }
+
+ public async Task<List<TelemetryHistorySourceCheckPoint>> GetCheckpointsBackup()
+ {
+ var response = await _webClient.GetTelemetryCheckPoints(new TelemetryGetCheckPointsRequest());
+ return response.Checkpoints
+ .Select(x => new TelemetryHistorySourceCheckPoint()
+ {
+ SourceName = x.SourceName,
+ Time = x.Time,
+ TotalCount = x.TotalCount
+ })
+ .ToList();
+ }
+
+ public async Task SaveCheckpointsBackup(List<TelemetryHistorySourceCheckPoint> checkPoints)
+ {
+ await _webClient.SetTelemetryCheckPoints(new TelemetrySetCheckPointsRequest()
+ {
+ Checkpoints = checkPoints.Select(x => new TelemetryCheckPoint()
+ {
+ SourceName = x.SourceName,
+ Time = x.Time,
+ TotalCount = x.TotalCount
+ }).ToList()
+ });
+ }
+
+ public void Dispose()
+ {
+
+ }
+ }
+}
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
index 340ecb13e..56a8b4a2b 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs
@@ -40,6 +40,7 @@ using Tango.PPC.Common.Statistics;
using Tango.PPC.Common.Storage;
using Tango.PPC.Common.Synchronization;
using Tango.PPC.Common.SystemInfo;
+using Tango.PPC.Common.Telemetry;
using Tango.PPC.Common.Threading;
using Tango.PPC.Common.ThreadLoading;
using Tango.PPC.Common.UpdatePackages;
@@ -54,6 +55,7 @@ using Tango.PPC.UI.Notifications;
using Tango.PPC.UI.PPCApplication;
using Tango.PPC.UI.Printing;
using Tango.PPC.UI.RemoteActions;
+using Tango.PPC.UI.Telemetry;
using Tango.PPC.UI.Threading;
using Tango.PPC.UI.ThreadLoading;
using Tango.PPC.UI.ViewModels;
@@ -118,6 +120,7 @@ namespace Tango.PPC.UI
TangoIOC.Default.Unregister<IStatisticsService>();
TangoIOC.Default.Unregister<IJobResumeManager>();
TangoIOC.Default.Unregister<ISMSNotificationProvider>();
+ TangoIOC.Default.Unregister<ITelemetryProvider>();
if (App.StartupArgs != null && App.StartupArgs.Contains("-webDebug"))
{
@@ -175,6 +178,7 @@ namespace Tango.PPC.UI
TangoIOC.Default.Register<IStatisticsService, DefaultStatisticsService>();
TangoIOC.Default.Register<IJobResumeManager, DefaultJobResumeManager>();
TangoIOC.Default.Register<ISMSNotificationProvider, DefaultSMSNotificationProvider>();
+ TangoIOC.Default.Register<ITelemetryProvider, DefaultTelemetryProvider>();
TangoIOC.Default.Register<LoadingViewVM>();
TangoIOC.Default.Register<MainViewVM>();
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/packages.config b/Software/Visual_Studio/PPC/Tango.PPC.UI/packages.config
index 9e3e48198..59e20edb2 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/packages.config
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/packages.config
@@ -1,15 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ControlzEx" version="3.0.2.4" targetFramework="net46" />
+ <package id="DotNetty.Buffers" version="0.4.6" targetFramework="net461" />
+ <package id="DotNetty.Codecs" version="0.4.6" targetFramework="net461" />
+ <package id="DotNetty.Codecs.Mqtt" version="0.4.6" targetFramework="net461" />
+ <package id="DotNetty.Common" version="0.4.6" targetFramework="net461" />
+ <package id="DotNetty.Handlers" version="0.4.6" targetFramework="net461" />
+ <package id="DotNetty.Transport" version="0.4.6" targetFramework="net461" />
+ <package id="EnterpriseLibrary.TransientFaultHandling" version="6.0.1304.0" targetFramework="net461" />
<package id="EntityFramework" version="6.2.0" targetFramework="net461" />
<package id="Expression.Blend.Sdk" version="1.0.2" targetFramework="net46" />
<package id="FontAwesome.WPF" version="4.7.0.9" targetFramework="net46" />
<package id="Google.Protobuf" version="3.4.1" targetFramework="net46" />
+ <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net461" />
+ <package id="Microsoft.Azure.Amqp" version="2.0.6" targetFramework="net461" />
+ <package id="Microsoft.Azure.Devices.Client" version="1.6.0" targetFramework="net461" />
+ <package id="Microsoft.Azure.Devices.Shared" version="1.3.0" targetFramework="net461" />
+ <package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net461" />
+ <package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net461" />
+ <package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net461" />
+ <package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net461" />
+ <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="1.1.0" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Logging" version="1.1.1" targetFramework="net461" />
+ <package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.1" targetFramework="net461" />
+ <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
+ <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
<package id="Microsoft.WindowsAPICodePack-Core" version="1.1.0.0" targetFramework="net461" />
+ <package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
+ <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
+ <package id="PCLCrypto" version="2.0.147" targetFramework="net461" />
+ <package id="PInvoke.BCrypt" version="0.3.2" targetFramework="net461" />
+ <package id="PInvoke.Kernel32" version="0.3.2" targetFramework="net461" />
+ <package id="PInvoke.NCrypt" version="0.3.2" targetFramework="net461" />
+ <package id="PInvoke.Windows.Core" version="0.3.2" targetFramework="net461" />
<package id="SimpleValidator" version="0.6.1.0" targetFramework="net46" />
+ <package id="System.AppContext" version="4.3.0" targetFramework="net461" />
+ <package id="System.Collections" version="4.3.0" targetFramework="net461" />
+ <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
+ <package id="System.ComponentModel" version="4.3.0" targetFramework="net461" />
+ <package id="System.Console" version="4.3.0" targetFramework="net461" />
<package id="System.Data.SQLite" version="1.0.108.0" targetFramework="net46" />
<package id="System.Data.SQLite.Core" version="1.0.108.0" targetFramework="net46" />
<package id="System.Data.SQLite.EF6" version="1.0.108.0" targetFramework="net46" />
<package id="System.Data.SQLite.Linq" version="1.0.108.0" targetFramework="net46" />
+ <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
+ <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
+ <package id="System.Globalization" version="4.3.0" targetFramework="net461" />
+ <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net461" />
+ <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Linq" version="4.3.0" targetFramework="net461" />
+ <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Net.Http" version="4.3.0" targetFramework="net461" />
+ <package id="System.Net.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Net.Sockets" version="4.3.0" targetFramework="net461" />
+ <package id="System.ObjectModel" version="4.3.0" targetFramework="net461" />
+ <package id="System.Reflection" version="4.3.0" targetFramework="net461" />
+ <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net461" />
+ <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
+ <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
+ <package id="System.Spatial" version="5.6.4" targetFramework="net461" />
+ <package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
+ <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />
+ <package id="System.Threading" version="4.3.0" targetFramework="net461" />
+ <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net461" />
+ <package id="System.Threading.Timer" version="4.3.0" targetFramework="net461" />
+ <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net461" />
+ <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net461" />
+ <package id="Validation" version="2.2.8" targetFramework="net461" />
+ <package id="WindowsAzure.Storage" version="7.0.0" targetFramework="net461" />
<package id="WPFMediaKit" version="2.2.0" targetFramework="net461" />
</packages> \ No newline at end of file
diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
index 09f5ea2ac..de9168cac 100644
--- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
+++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs
@@ -782,6 +782,7 @@ namespace Tango.Emulations.Emulators
{
var res = new StartMachineStatusUpdateResponse();
res.Status = MachineStatus;
+ res.Status.OverallTemperature = Cursor.Position.Y;
if (!EmulateCorruption)
{
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs
index 36604ba3c..79adfc0da 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs
@@ -28,6 +28,7 @@ namespace Tango.Integration.Operation
protected double _last_progress;
protected const int PROGRESS_REPORT_RANGE_METERS = 5;
protected bool loggedContinueMessage;
+ private DateTime _lastProgressLogDateTime;
#region Events
@@ -341,25 +342,27 @@ namespace Tango.Integration.Operation
protected virtual void InvalidateJobProgress(JobStatus s)
{
JobStatus = s;
-
- if (_last_progress != s.Progress)
+
+ if (DateTime.UtcNow > _lastProgressLogDateTime.AddSeconds(5))
{
- //if (LogManager.Categories.Exists(x => x == LogCategory.Debug))
- //{
+ _lastProgressLogDateTime = DateTime.UtcNow;
+
+ if (LogManager.Categories.Exists(x => x == LogCategory.Debug))
+ {
LogManager.Log($"Updating job progress {s.Progress}/{Status.TotalProgress}...");
- //}
- //else
- //{
- // if (s.Progress <= PROGRESS_REPORT_RANGE_METERS || s.Progress >= Status.TotalProgress - PROGRESS_REPORT_RANGE_METERS)
- // {
- // LogManager.Log($"Updating job progress {s.Progress}/{Status.TotalProgress}...");
- // }
- // else if (!loggedContinueMessage)
- // {
- // loggedContinueMessage = true;
- // LogManager.Log($"Progress logging will continue {PROGRESS_REPORT_RANGE_METERS} meters before completion...");
- // }
- //}
+ }
+ else
+ {
+ if (s.Progress <= PROGRESS_REPORT_RANGE_METERS || s.Progress >= Status.TotalProgress - PROGRESS_REPORT_RANGE_METERS)
+ {
+ LogManager.Log($"Updating job progress {s.Progress}/{Status.TotalProgress}...");
+ }
+ else if (!loggedContinueMessage)
+ {
+ loggedContinueMessage = true;
+ LogManager.Log($"Progress logging will continue {PROGRESS_REPORT_RANGE_METERS} meters before completion...");
+ }
+ }
}
if (s.Progress < 0)
@@ -378,16 +381,16 @@ namespace Tango.Integration.Operation
{
LogManager.Log($"Invalid job progress received '{s.Progress}' while last progress was '{_last_progress}'.");
}
-
+
_last_progress = s.Progress;
-
+
List<Segment> unit_segments = new List<Segment>();
Status.Progress = s.Progress;
Status.RemainingTime = Status.TotalTime - Job.TranslateProgressToTime(Status.Progress, ProcessParameters);
Status.RemainingProgress = Status.TotalProgress - Status.Progress;
- if((s.Progress < Status.SettingUpTotalProgress) || (Status.SettingUpProgress < Status.SettingUpTotalProgress))
+ if ((s.Progress < Status.SettingUpTotalProgress) || (Status.SettingUpProgress < Status.SettingUpTotalProgress))
{
Status.SettingUpProgress = Math.Min(s.Progress, this.Status.SettingUpTotalProgress);
Status.IsSettingUp = true;
@@ -437,12 +440,12 @@ namespace Tango.Integration.Operation
break;
}
}
- else if(ResumeConfig != null && ResumeConfig.GlobalStartPosition > 0)
+ else if (ResumeConfig != null && ResumeConfig.GlobalStartPosition > 0)
{
if (!Status.IsSettingUp && s.Progress <= previousUnitsLengthWithoutThis + unitLength + ProcessParameters.DryerBufferLengthMeters)
{
currentUnitProgress = s.Progress - previousUnitsLengthWithoutThis - ProcessParameters.DryerBufferLengthMeters;
- //LogManager.Log($" JOB HANDLER currentUnitProgress before ={currentUnitProgress} progress = {s.Progress}");
+ //LogManager.Log($" JOB HANDLER currentUnitProgress before ={currentUnitProgress} progress = {s.Progress}");
break;
}
}
@@ -476,7 +479,7 @@ namespace Tango.Integration.Operation
Status.CurrentUnitTotalProgress = Status.RemainingUnits > 1 && Job.EnableInterSegment ? Job.Length + (Job.InterSegmentLength) : Job.Length;
- if (s.Message != _lastStatusMessage )
+ if (s.Message != _lastStatusMessage)
{
Status.Message = s.Message;
}
diff --git a/Software/Visual_Studio/Tango.Telemetry/Destinations/TelemetryAzureHubBatchDestination.cs b/Software/Visual_Studio/Tango.Telemetry/Destinations/TelemetryAzureHubBatchDestination.cs
new file mode 100644
index 000000000..10bc3981a
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Telemetry/Destinations/TelemetryAzureHubBatchDestination.cs
@@ -0,0 +1,208 @@
+using Microsoft.Azure.Devices.Client;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Logging;
+using Tango.Telemetry.Helpers;
+// NEW:
+using System.Timers;
+
+namespace Tango.Telemetry.Destinations
+{
+ /// <summary>
+ /// Represents a telemetry destination that publishes telemetry data to Azure IoT Hub using MQTT transport.
+ /// Now always batches and flushes once per second on a timer.
+ /// </summary>
+ public class TelemetryAzureHubBatchDestination : ExtendedObject, ITelemetryDestination
+ {
+ private DeviceClient _hubClient;
+ private int _batchSize; // kept for compatibility (no longer used for triggering sends)
+ private ConcurrentList<Message> _batch;
+
+ // NEW: timer + lock to coordinate flushes
+ private Timer _flushTimer;
+ private readonly object _batchLock = new object();
+
+ private class ADXPAckage
+ {
+ public String Type { get; set; }
+ public String Environment { get; set; }
+ public String MachineType { get; set; }
+ public String SerialNumber { get; set; }
+ public String Organization { get; set; }
+ public String Site { get; set; }
+ public ITelemetry Telemetry { get; set; }
+ public DateTime UploadTime { get; set; }
+ public DateTime CreatedTime { get; set; }
+ public int Version { get; set; }
+ public String ToPayload() => JsonConvert.SerializeObject(this, Formatting.None);
+ }
+
+ public string Name { get; set; } = "Azure IoT Hub";
+ public string ConnectionString { get; private set; }
+ public ConnectionStatus HubConnectionStatus { get; private set; }
+ public IReadOnlyList<TelemetrySourceTypes> SupportedSourceTypes { get; private set; }
+
+ /// <summary>
+ /// Kept for backward compatibility. Value is clamped 1..10 but not used to trigger flushes anymore.
+ /// </summary>
+ public int BatchSize { get => _batchSize; set => _batchSize = Math.Min(Math.Max(1, value), 10); }
+
+ private TelemetryAzureHubBatchDestination()
+ {
+ _batch = new ConcurrentList<Message>();
+ HubConnectionStatus = ConnectionStatus.Connected;
+ SupportedSourceTypes = new List<TelemetrySourceTypes>()
+ {
+ TelemetrySourceTypes.PendingStorage,
+ TelemetrySourceTypes.Streaming,
+ TelemetrySourceTypes.ExternalStorage
+ };
+ BatchSize = 1;
+ }
+
+ public TelemetryAzureHubBatchDestination(string connectionString) : this()
+ {
+ ConnectionString = connectionString;
+ }
+
+ public Task<bool> IsAvailable()
+ {
+ if (InternetConnectivity.IsInternetAvailable())
+ {
+ if (_hubClient == null) return Task.FromResult(true);
+ return Task.FromResult(HubConnectionStatus == ConnectionStatus.Connected);
+ }
+ return Task.FromResult(false);
+ }
+
+ public Task Publish(TelemetryPublishPackage package, List<KeyValuePair<string, string>> properties)
+ {
+ if (_hubClient == null)
+ {
+ _hubClient = DeviceClient.CreateFromConnectionString(ConnectionString, TransportType.Mqtt);
+ _hubClient.OperationTimeoutInMilliseconds = 2000;
+ _hubClient.SetConnectionStatusChangesHandler((status, reason) =>
+ {
+ HubConnectionStatus = status;
+ LogManager.Log($"IoT hub status changed to: {status}, Reason: {reason}.", LogCategory.Info);
+ });
+
+ // NEW: start the periodic flusher (every 1s)
+ EnsureFlushTimer();
+ }
+
+ var adxPackage = new ADXPAckage
+ {
+ Type = package.TelemetryName,
+ Version = package.TelemetryVersion,
+ Environment = package.Environment,
+ MachineType = package.MachineType,
+ SerialNumber = package.SerialNumber,
+ Organization = package.Organization,
+ Site = package.Site,
+ UploadTime = DateTime.UtcNow,
+ CreatedTime = package.PendingTelemetry.TelemetryObject.Time,
+ Telemetry = package.PendingTelemetry.TelemetryObject
+ };
+
+ var message = new Message(Encoding.UTF8.GetBytes(adxPackage.ToPayload()))
+ {
+ ContentType = "application/json",
+ ContentEncoding = "utf-8"
+ };
+
+ foreach (var prop in properties)
+ message.Properties.Add(prop.Key, prop.Value);
+
+ // NEW: always enqueue; timer decides when to send
+ lock (_batchLock)
+ {
+ _batch.Add(message);
+ }
+ LogManager.Log("Queued telemetry message for 1s batch flush.", LogCategory.Debug);
+
+ return Task.FromResult(true);
+ }
+
+ // NEW: create the 1s timer (idempotent)
+ private void EnsureFlushTimer()
+ {
+ if (_flushTimer != null) return;
+
+ _flushTimer = new Timer(1000);
+ _flushTimer.AutoReset = true;
+ _flushTimer.Elapsed += async (s, e) =>
+ {
+ try
+ {
+ await FlushBatchAsync().ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ // If send fails, drop connection so IsAvailable() reflects it and upstream can retry later
+ try { _hubClient?.Dispose(); } catch { /* ignore */ }
+ _hubClient = null;
+ LogManager.Log($"Azure IoT Hub flush failed: {ex.Message}", LogCategory.Warning);
+ }
+ };
+ _flushTimer.Start();
+ }
+
+ // NEW: send whatever accumulated since last tick
+ private async Task FlushBatchAsync()
+ {
+ List<Message> toSend = null;
+
+ lock (_batchLock)
+ {
+ if (_batch.Count == 0) return;
+ toSend = _batch.ToList();
+ _batch.Clear();
+ }
+
+ LogManager.Log($"Sending telemetry batch of {toSend.Count} messages to Azure IoT Hub.", LogCategory.Debug);
+ await _hubClient.SendEventBatchAsync(toSend);
+ }
+
+ public void Dispose()
+ {
+ // NEW: stop timer first to avoid races
+ if (_flushTimer != null)
+ {
+ _flushTimer.Stop();
+ _flushTimer.Dispose();
+ _flushTimer = null;
+ }
+
+ // Flush any remaining messages synchronously
+ try
+ {
+ List<Message> toSend = null;
+ lock (_batchLock)
+ {
+ if (_batch.Count > 0)
+ {
+ toSend = _batch.ToList();
+ _batch.Clear();
+ }
+ }
+ if (_hubClient != null && toSend != null && toSend.Count > 0)
+ {
+ LogManager.Log($"Flushing {toSend.Count} remaining messages to Azure IoT Hub.", LogCategory.Info);
+ _hubClient.SendEventBatchAsync(toSend).GetAwaiter().GetResult();
+ }
+ }
+ finally
+ {
+ _hubClient?.Dispose();
+ }
+ }
+
+ public override string ToString() => Name;
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSource.cs b/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSource.cs
index 657fa83e8..a5b2da647 100644
--- a/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSource.cs
+++ b/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSource.cs
@@ -37,7 +37,7 @@ namespace Tango.Telemetry.Sources
_diagnosticsQueue = new List<StartDiagnosticsResponse>();
}
- public TelemetryDiagnosticsStreamingSource(IMachineOperator machineOperator) : base()
+ public TelemetryDiagnosticsStreamingSource(IMachineOperator machineOperator) : this()
{
_machineOperator = machineOperator;
_machineOperator.DiagnosticsDataAvailable += DiagnosticsDataAvailable;
diff --git a/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSourceConfig.cs b/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSourceConfig.cs
index c161ed680..032d318d9 100644
--- a/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSourceConfig.cs
+++ b/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryDiagnosticsStreamingSourceConfig.cs
@@ -13,7 +13,7 @@ namespace Tango.Telemetry.Sources
public TelemetryDiagnosticsStreamingSourceConfig()
{
- DiagnosticsSamplingInterval = TimeSpan.FromSeconds(10);
+ DiagnosticsSamplingInterval = TimeSpan.FromSeconds(60);
}
}
}
diff --git a/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryJobStatusSource.cs b/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryJobStatusSource.cs
index 93a5cc54e..9f7488909 100644
--- a/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryJobStatusSource.cs
+++ b/Software/Visual_Studio/Tango.Telemetry/Sources/TelemetryJobStatusSource.cs
@@ -6,6 +6,8 @@ using System.Threading.Tasks;
using Tango.BL.Entities;
using Tango.Integration.Operation;
using Tango.Telemetry.Telemetries;
+// NEW:
+using System.Timers;
namespace Tango.Telemetry.Sources
{
@@ -17,6 +19,12 @@ namespace Tango.Telemetry.Sources
private String _groupID;
private DateTime _startTime;
+ // NEW: throttle state
+ private readonly object _lock = new object();
+ private DateTime _lastStatusArrivedUtc;
+ private DateTime _lastEmittedUtc;
+ private Timer _emitTimer; // ticks every 1s
+
public bool IsStarted { get; private set; }
public string Name { get; } = "Job Status Streaming";
public bool RequiresTelemetryDuplicationTracking { get; }
@@ -34,6 +42,15 @@ namespace Tango.Telemetry.Sources
{
IsStarted = true;
_machineOperator.PrintingStarted += MachineOperator_PrintingStarted;
+
+ // NEW: start 1s emitter (idempotent)
+ if (_emitTimer == null)
+ {
+ _emitTimer = new Timer(1000);
+ _emitTimer.AutoReset = true;
+ _emitTimer.Elapsed += EmitTimer_Elapsed;
+ _emitTimer.Start();
+ }
}
}
@@ -43,6 +60,15 @@ namespace Tango.Telemetry.Sources
{
IsStarted = false;
_machineOperator.PrintingStarted -= MachineOperator_PrintingStarted;
+
+ // NEW: stop timer
+ if (_emitTimer != null)
+ {
+ _emitTimer.Stop();
+ _emitTimer.Elapsed -= EmitTimer_Elapsed;
+ _emitTimer.Dispose();
+ _emitTimer = null;
+ }
}
}
@@ -58,70 +84,80 @@ namespace Tango.Telemetry.Sources
}
}
- private void JobHandler_StatusChanged(object sender, RunningJobStatus status)
+ // NEW: timer tick — emit only the latest status observed within last 5 seconds, once per tick
+ private void EmitTimer_Elapsed(object sender, ElapsedEventArgs e)
{
- if (IsStarted)
- {
- TelemetryJobStatus tStatus = new TelemetryJobStatus();
+ if (!IsStarted) return;
- tStatus.JobName = _job?.Name;
+ TelemetryJobStatus toEmit = null;
+ DateTime now = DateTime.UtcNow;
- if (status.ProgressMinusSettingUp > 0)
- {
- tStatus.Status = TelemetryJobStatus.JobStatus.InProgress;
- }
-
- if (status.IsCompleted)
- {
- tStatus.Status = TelemetryJobStatus.JobStatus.Completed;
- }
-
- if (status.IsFailed)
+ lock (_lock)
+ {
+ // Only emit if we have a newer status than last emitted,
+ // and that status is fresh (arrived within the last 5 seconds).
+ if (_lastStatus != null &&
+ _lastStatusArrivedUtc > _lastEmittedUtc &&
+ (now - _lastStatusArrivedUtc) <= TimeSpan.FromSeconds(5))
{
- tStatus.Status = TelemetryJobStatus.JobStatus.Failed;
+ toEmit = _lastStatus;
+ _lastEmittedUtc = now; // mark emission (1 per tick max)
}
+ }
- if (status.IsCanceled)
+ if (toEmit != null)
+ {
+ TelemetryAvailable?.Invoke(this, new TelemetryAvailableEventArgs
{
- tStatus.Status = TelemetryJobStatus.JobStatus.Aborted;
- }
-
- tStatus.ID = _groupID;
- tStatus.TotalTime = status.TotalTime;
- tStatus.RemainingTime = status.RemainingTime;
-
- tStatus.Progress = status.ProgressMinusSettingUp;
- tStatus.TotalProgress = status.TotalProgressMinusSettingUp;
+ TelemetryObject = toEmit,
+ DisableDeliveryRetries = true
+ });
+ }
+ }
- tStatus.CurrentUnit = status.CurrentUnit;
- tStatus.RemainingUnits = status.RemainingUnits;
+ private void JobHandler_StatusChanged(object sender, RunningJobStatus status)
+ {
+ if (!IsStarted) return;
- tStatus.CurrentUnitProgress = status.CurrentUnitProgress;
- tStatus.CurrentUnitTotalProgress = status.CurrentUnitTotalProgress;
+ // CHANGED: just update the latest snapshot fast; do NOT emit here.
+ var tStatus = new TelemetryJobStatus
+ {
+ JobName = _job?.Name,
+ ID = _groupID,
+ TotalTime = status.TotalTime,
+ RemainingTime = status.RemainingTime,
+ Progress = status.ProgressMinusSettingUp,
+ TotalProgress = status.TotalProgressMinusSettingUp,
+ CurrentUnit = status.CurrentUnit,
+ RemainingUnits = status.RemainingUnits,
+ CurrentUnitProgress = status.CurrentUnitProgress,
+ CurrentUnitTotalProgress = status.CurrentUnitTotalProgress,
+ Message = status.Message
+ };
- tStatus.Message = status.Message;
+ if (status.ProgressMinusSettingUp > 0) tStatus.Status = TelemetryJobStatus.JobStatus.InProgress;
+ if (status.IsCompleted) tStatus.Status = TelemetryJobStatus.JobStatus.Completed;
+ if (status.IsFailed) tStatus.Status = TelemetryJobStatus.JobStatus.Failed;
+ if (status.IsCanceled) tStatus.Status = TelemetryJobStatus.JobStatus.Aborted;
+ lock (_lock)
+ {
_lastStatus = tStatus;
-
- TelemetryAvailable?.Invoke(this, new TelemetryAvailableEventArgs()
- {
- TelemetryObject = tStatus,
- DisableDeliveryRetries = true
- });
+ _lastStatusArrivedUtc = DateTime.UtcNow;
}
}
private void JobHandler_Failed(object sender, Exception e)
{
- if (_lastStatus != null)
+ // CHANGED: update the latest snapshot and let the timer emit it (within ~1s)
+ lock (_lock)
{
- _lastStatus.Message = e.FlattenMessage();
-
- TelemetryAvailable?.Invoke(this, new TelemetryAvailableEventArgs()
+ if (_lastStatus != null)
{
- TelemetryObject = _lastStatus,
- DisableDeliveryRetries = true
- });
+ _lastStatus.Message = e.FlattenMessage();
+ _lastStatus.Status = TelemetryJobStatus.JobStatus.Failed;
+ _lastStatusArrivedUtc = DateTime.UtcNow;
+ }
}
}
diff --git a/Software/Visual_Studio/Tango.Telemetry/Tango.Telemetry.csproj b/Software/Visual_Studio/Tango.Telemetry/Tango.Telemetry.csproj
index 611734724..dc61f443d 100644
--- a/Software/Visual_Studio/Tango.Telemetry/Tango.Telemetry.csproj
+++ b/Software/Visual_Studio/Tango.Telemetry/Tango.Telemetry.csproj
@@ -242,6 +242,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Destinations\TelemetryAzureHubBatchDestination.cs" />
<Compile Include="Helpers\DateTimeUTCFixer.cs" />
<Compile Include="Destinations\TelemetryAzureHubDestination.cs" />
<Compile Include="ExtensionMethods\ITelemetryExtensions.cs" />
diff --git a/Software/Visual_Studio/Tango.Telemetry/TelemetryLiteDBStorageManager.cs b/Software/Visual_Studio/Tango.Telemetry/TelemetryLiteDBStorageManager.cs
index aa50041ca..ab0ff2b58 100644
--- a/Software/Visual_Studio/Tango.Telemetry/TelemetryLiteDBStorageManager.cs
+++ b/Software/Visual_Studio/Tango.Telemetry/TelemetryLiteDBStorageManager.cs
@@ -56,23 +56,13 @@ namespace Tango.Telemetry
Directory.CreateDirectory(Path.GetDirectoryName(DatabasePath));
- String backupPath = DatabasePath + ".bak";
-
if (!File.Exists(DatabasePath))
{
- if (File.Exists(backupPath))
- {
- LogManager.Log("Telemetry database missing. Attempting to restore from backup.", LogCategory.Error);
- File.Copy(backupPath, DatabasePath, overwrite: true);
- }
- else
- {
- LogManager.Log("Telemetry database was not found. A new one will be created and source checkpoints will be recovered from the remote service if required.", LogCategory.Critical);
+ LogManager.Log("Telemetry database was not found. A new one will be created and source checkpoints will be recovered from the remote service if required.", LogCategory.Critical);
- if (_checkpointsRecoveryClient == null && EnableCheckPointsRecovery && EnforceCheckpointsRecovery)
- {
- throw new NullReferenceException("No TelemetryCheckpointsRecoveryClient was introduced. Telemetry Storage manager should not operate.");
- }
+ if (_checkpointsRecoveryClient == null && EnableCheckPointsRecovery && EnforceCheckpointsRecovery)
+ {
+ throw new NullReferenceException("No TelemetryCheckpointsRecoveryClient was introduced. Telemetry Storage manager should not operate.");
}
}
diff --git a/Software/Visual_Studio/Tango.Telemetry/TelemetryPublisherConfiguration.cs b/Software/Visual_Studio/Tango.Telemetry/TelemetryPublisherConfiguration.cs
index ceb405a4e..07ef8061e 100644
--- a/Software/Visual_Studio/Tango.Telemetry/TelemetryPublisherConfiguration.cs
+++ b/Software/Visual_Studio/Tango.Telemetry/TelemetryPublisherConfiguration.cs
@@ -42,7 +42,7 @@ namespace Tango.Telemetry
/// <summary>
/// Maximum number of telemetry packages allowed in memory queues before rejecting new packages.
/// </summary>
- public int MaxPendingTelemetries { get; set; } = 200;
+ public int MaxPendingTelemetries { get; set; } = 10000;
/// <summary>
/// Whether exponential backoff should be applied to retry logic per destination.
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
index 41266cda5..a46732956 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
@@ -746,40 +746,40 @@ namespace Tango.MachineService.Controllers
}
//Send Jobs
- if (request.RequestJobs)
- {
- var jobs = new JobsCollectionBuilder(db).Set(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).WithSegments().WithBrushStops().Query(x => x.Take(request.MaxJobs).OrderByDescending(z => z.LastUpdated)).BuildList();
+ //if (request.RequestJobs)
+ //{
+ // var jobs = new JobsCollectionBuilder(db).Set(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).WithSegments().WithBrushStops().Query(x => x.Take(request.MaxJobs).OrderByDescending(z => z.LastUpdated)).BuildList();
- foreach (var job in jobs)
- {
- JobDTO dto = JobDTO.FromObservable(job);
- response.Jobs.Add(dto);
- }
- }
+ // foreach (var job in jobs)
+ // {
+ // JobDTO dto = JobDTO.FromObservable(job);
+ // response.Jobs.Add(dto);
+ // }
+ //}
//Send Job Runs
- if (request.RequestJobRuns)
- {
- var jobRuns = db.JobRuns.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxJobRuns).OrderByDescending(x => x.LastUpdated).ToList();
+ //if (request.RequestJobRuns)
+ //{
+ // var jobRuns = db.JobRuns.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxJobRuns).OrderByDescending(x => x.LastUpdated).ToList();
- foreach (var jobRun in jobRuns)
- {
- JobRunDTO dto = JobRunDTO.FromObservable(jobRun);
- response.JobRuns.Add(dto);
- }
- }
+ // foreach (var jobRun in jobRuns)
+ // {
+ // JobRunDTO dto = JobRunDTO.FromObservable(jobRun);
+ // response.JobRuns.Add(dto);
+ // }
+ //}
//Send Machine Events
- if (request.RequestMachineEvents)
- {
- var machineEvents = db.MachinesEvents.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxMachinesEvents).OrderByDescending(x => x.LastUpdated).ToList();
+ //if (request.RequestMachineEvents)
+ //{
+ // var machineEvents = db.MachinesEvents.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxMachinesEvents).OrderByDescending(x => x.LastUpdated).ToList();
- foreach (var machineEvent in machineEvents)
- {
- MachinesEventDTO dto = MachinesEventDTO.FromObservable(machineEvent);
- response.MachineEvents.Add(dto);
- }
- }
+ // foreach (var machineEvent in machineEvents)
+ // {
+ // MachinesEventDTO dto = MachinesEventDTO.FromObservable(machineEvent);
+ // response.MachineEvents.Add(dto);
+ // }
+ //}
//Send DataStore Items
if (request.RequestDataStoreItems)
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
index e9c766c5d..39d815e9d 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
@@ -82,6 +82,13 @@
<HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
+ <Reference Include="Microsoft.Data.Edm, Version=5.8.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Data.Edm.5.8.5\lib\net40\Microsoft.Data.Edm.dll</HintPath>
+ <SpecificVersion>False</SpecificVersion>
+ </Reference>
+ <Reference Include="Microsoft.Data.OData, Version=5.8.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\Microsoft.Data.OData.5.8.5\lib\net40\Microsoft.Data.OData.dll</HintPath>
+ </Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.0.5\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
</Reference>
@@ -224,6 +231,9 @@
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System.Security" />
+ <Reference Include="System.Spatial, Version=5.8.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\..\packages\System.Spatial.5.8.5\lib\net40\System.Spatial.dll</HintPath>
+ </Reference>
<Reference Include="System.Transactions" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll</HintPath>
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config
index 85260c32c..d9c0a6bdd 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config
@@ -176,7 +176,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ <bindingRedirect oldVersion="0.0.0.0-5.8.5.0" newVersion="5.8.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -184,7 +184,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
+ <bindingRedirect oldVersion="0.0.0.0-5.8.5.0" newVersion="5.8.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
@@ -206,6 +206,10 @@
<assemblyIdentity name="Z.EntityFramework.Extensions" publicKeyToken="59b66d028979105b" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.50.0" newVersion="4.0.50.0" />
</dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-5.8.5.0" newVersion="5.8.5.0" />
+ </dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/packages.config b/Software/Visual_Studio/Web/Tango.MachineService/packages.config
index a944a6267..430a39226 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/packages.config
+++ b/Software/Visual_Studio/Web/Tango.MachineService/packages.config
@@ -31,6 +31,8 @@
<package id="Microsoft.Azure.Devices.Shared" version="1.30.3" targetFramework="net461" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.3" targetFramework="net45" />
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net461" />
+ <package id="Microsoft.Data.Edm" version="5.8.5" targetFramework="net461" />
+ <package id="Microsoft.Data.OData" version="5.8.5" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="5.0.5" targetFramework="net461" />
<package id="Microsoft.Net.Compilers" version="2.4.0" targetFramework="net46" developmentDependency="true" />
<package id="Microsoft.Owin" version="4.2.2" targetFramework="net461" />
@@ -47,6 +49,7 @@
<package id="System.Data.SQLite.Core" version="1.0.108.0" targetFramework="net46" />
<package id="System.Data.SQLite.EF6" version="1.0.108.0" targetFramework="net46" />
<package id="System.Data.SQLite.Linq" version="1.0.108.0" targetFramework="net46" />
+ <package id="System.Spatial" version="5.8.5" targetFramework="net461" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />
<package id="Twilio" version="7.6.0" targetFramework="net461" />
<package id="WebGrease" version="1.5.2" targetFramework="net45" />