using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Entities;
using Tango.Core;
using Tango.Integration.Operation;
using Tango.Integration.ExternalBridge;
using Tango.PMR.Connection;
using Tango.Transport.Adapters;
using Tango.Settings;
using Tango.Logging;
using Tango.BL.Builders;
using Tango.Core.DI;
using Tango.PPC.Common.Messages;
using Tango.Emulations.Emulators;
using Tango.Transport.Transporters;
using Tango.Integration;
using Tango.Transport;
using System.Threading;
using Tango.Core.ExtensionMethods;
namespace Tango.PPC.Common.Connection
{
///
/// Represents the default .
///
///
///
public class DefaultMachineProvider : ExtendedObject, IMachineProvider
{
private bool _isInitialized;
private Thread _connection_thread;
private ObservablesContext _context;
private Machine _machine;
///
/// Gets the database machine entity associated with the current machine.
///
public Machine Machine
{
get
{
return _machine;
}
private set
{
_machine = value;
RaisePropertyChangedAuto();
}
}
private IMachineOperator _machineOperator;
///
/// Gets the machine operator.
///
public IMachineOperator MachineOperator
{
get
{
return _machineOperator;
}
private set
{
_machineOperator = value;
RaisePropertyChangedAuto();
}
}
///
/// Initializes a new instance of the class.
///
public DefaultMachineProvider()
{
MachineOperator = new MachineOperator();
MachineOperator.EnableEventsNotification = true;
MachineOperator.EnableJobResume = true;
MachineOperator.UseKeepAlive = true;
MachineOperator.EnableMachineStatusUpdates = true;
MachineOperator.EnableDiagnostics = false;
MachineOperator.EnableEmbeddedDebugging = false;
MachineOperator.FirmwareUpgradeMode = Integration.Upgrade.FirmwareUpgradeModes.DFU | Integration.Upgrade.FirmwareUpgradeModes.TFP_PACKAGE;
var settings = SettingsManager.Default.GetOrCreate();
MachineOperator.JobUploadStrategy = settings.JobUploadStrategy;
MachineOperator.GradientGenerationConfiguration.IsEnabled = settings.EnableGradientGeneration;
MachineOperator.GradientGenerationConfiguration.ResolutionCM = settings.GradientGenerationResolution;
MachineOperator.EmergencyNotificationProvider.Address = settings.EmergencyComPort;
MachineOperator.EmergencyNotificationProvider.IsEnabled = settings.EnableEmergencyNotifications;
MachineOperator.EnableJobLiquidQuantityValidation = settings.EnableJobLiquidQuantityValidation;
}
private async void ConnectionThreadMethod()
{
while (true)
{
if (MachineOperator.State != TransportComponentState.Connected)
{
try
{
Thread.Sleep(2000);
LogManager.Log("Starting machine connection procedure...", LogCategory.Debug);
var settings = SettingsManager.Default.GetOrCreate();
if (!Machine.IsDemo)
{
if (String.IsNullOrWhiteSpace(settings.EmbeddedComPort))
{
TimeSpan timeout = TimeSpan.FromSeconds(SettingsManager.Default.GetOrCreate().MachineScanningTimeoutSeconds);
LogManager.Log("Scanning for machine on available serial ports...", LogCategory.Debug);
Transport.Discovery.UsbCommunicationScanner scanner = new Transport.Discovery.UsbCommunicationScanner(UsbSerialBaudRates.BR_115200);
var response = await scanner.Scan(new ConnectRequest() { Password = "1234" }, settings.EmbeddedDeviceHint, timeout);
LogManager.Log("Machine discovered on port: " + response.Adapter.Address, LogCategory.Debug);
LogManager.Log("Device Information:", LogCategory.Debug);
LogManager.Log(response.Response.DeviceInformation.ToJsonString(), LogCategory.Debug);
LogManager.Log("Disconnecting machine operator...", LogCategory.Debug);
await MachineOperator.Disconnect();
MachineOperator.Adapter = response.Adapter;
MachineOperator.JobHandlingMode = JobHandlerModes.SettingUp;
LogManager.Log("Connecting machine operator...", LogCategory.Debug);
try
{
await MachineOperator.Connect();
}
catch (Exception)
{
await response.Adapter.Disconnect();
throw;
}
await Task.Delay(1000);
await MachineOperator.UploadHardwareConfiguration(Machine.Configuration.HardwareVersion, Machine.Configuration);
MachineOperator.UseKeepAlive = true;
}
else
{
LogManager.Log($"Connecting to machine on {settings.EmbeddedComPort}...", LogCategory.Debug);
UsbTransportAdapter adapter = new UsbTransportAdapter(settings.EmbeddedComPort, UsbSerialBaudRates.BR_115200);
MachineOperator.Adapter = adapter;
MachineOperator.JobHandlingMode = JobHandlerModes.SettingUp;
try
{
await MachineOperator.Connect();
}
catch (Exception)
{
await adapter.Disconnect();
throw;
}
await Task.Delay(1000);
await MachineOperator.UploadHardwareConfiguration(Machine.Configuration.HardwareVersion, Machine.Configuration);
MachineOperator.UseKeepAlive = true;
}
}
else
{
LogManager.Log("Application in demo mode!");
var emulator_channel_name = "emulator-" + Guid.NewGuid().ToString();
LogManager.Log("Starting embedded emulator...");
MachineEmulator emulator = new MachineEmulator(new BasicTransporter(new MemoryTransportAdapter(emulator_channel_name)));
await emulator.Start();
LogManager.Log("Emulator started. Connecting to emulator...");
MemoryTransportAdapter adapter = new MemoryTransportAdapter(emulator_channel_name);
MachineOperator.Adapter = adapter;
MachineOperator.JobHandlingMode = JobHandlerModes.SettingUp;
LogManager.Log("Connecting machine operator...");
await MachineOperator.Connect();
await Task.Delay(1000);
await MachineOperator.UploadHardwareConfiguration(Machine.Configuration.HardwareVersion, Machine.Configuration);
}
}
catch (Exception ex)
{
LogManager.Log(ex, LogCategory.Debug, "Error while trying to scan and connect to the machine.");
}
}
Thread.Sleep(5000);
}
}
///
/// Initializes this machine provider start machine port scanning and connection.
///
public void Init(Machine machine, ObservablesContext context)
{
if (!_isInitialized)
{
LogManager.Log("Initializing machine operator...");
_isInitialized = true;
LogManager.Log("Retrieving first machine database entry...");
_context = context;
Machine = machine;
if (Machine != null)
{
LogManager.Log("First machine entry found. Machine serial number is: " + Machine.SerialNumber + ".");
ConnectToMachine();
}
else
{
LogManager.Log("No machine entry found on database. Could not connect to the embedded device!", LogCategory.Error);
}
}
}
///
/// Tries to connect to the machine by scanning all available serial ports.
/// The timeout for a scan cycle is specified on .
///
private void ConnectToMachine()
{
if (_connection_thread == null)
{
_connection_thread = new Thread(ConnectionThreadMethod);
_connection_thread.IsBackground = true;
_connection_thread.Start();
}
}
///
/// Saves the machine settings.
///
///
public async Task SaveMachine()
{
await _context.SaveChangesAsync();
Machine = await new MachineBuilder(_context).SetFirst().WithSettings().BuildAsync();
TangoMessenger.Default.Send(new MachineSettingsSavedMessage() { Machine = Machine });
}
///
/// Creates and connects a machine operator with no continuous requests at all.
///
///
public static async Task CreateMinimalMachineOperator(Action onProgress = null)
{
LogManager.Default.Log("Creating minimal machine operator...");
var machineOperator = new MachineOperator();
machineOperator.EnableDiagnostics = false;
machineOperator.EnableEmbeddedDebugging = false;
machineOperator.EnableEventsNotification = false;
machineOperator.EnableMachineStatusUpdates = false;
machineOperator.EnableJobResume = false;
LogManager.Default.Log("Starting machine connection procedure...");
var settings = SettingsManager.Default.GetOrCreate();
if (String.IsNullOrWhiteSpace(settings.EmbeddedComPort))
{
TimeSpan timeout = TimeSpan.FromSeconds(SettingsManager.Default.GetOrCreate().MachineScanningTimeoutSeconds);
onProgress?.Invoke("Scanning for the machine...");
LogManager.Default.Log("Scanning for machine on available serial ports...");
Transport.Discovery.UsbCommunicationScanner scanner = new Transport.Discovery.UsbCommunicationScanner(UsbSerialBaudRates.BR_115200);
var response = await scanner.Scan(new ConnectRequest() { Password = "1234" }, timeout);
onProgress?.Invoke("Machine discovered on port: " + response.Adapter.Address);
LogManager.Default.Log("Machine discovered on port: " + response.Adapter.Address);
LogManager.Default.Log("Device Information:");
LogManager.Default.Log(response.Response.DeviceInformation.ToJsonString());
machineOperator.Adapter = response.Adapter;
machineOperator.JobHandlingMode = JobHandlerModes.SettingUp;
LogManager.Default.Log("Connecting machine operator...");
onProgress?.Invoke("Connecting machine operator...");
await machineOperator.Connect();
}
else
{
LogManager.Default.Log($"Connecting to machine on {settings.EmbeddedComPort}...");
onProgress?.Invoke($"Connecting to machine on {settings.EmbeddedComPort}...");
UsbTransportAdapter adapter = new UsbTransportAdapter(settings.EmbeddedComPort, UsbSerialBaudRates.BR_115200);
machineOperator.Adapter = adapter;
machineOperator.JobHandlingMode = JobHandlerModes.SettingUp;
await machineOperator.Connect();
}
return machineOperator;
}
}
}