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; } } }