using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Settings;
using Tango.Web;
using Tango.Web.Security;
namespace Tango.PPC.Common.Web
{
public class PPCWebClient : PPCWebClientBase
{
public PPCWebClient(DeploymentSlot environment) : base(environment)
{
}
public PPCWebClient(DeploymentSlot environment, string token) : base(environment, token)
{
}
public PPCWebClient(string token) : this(SettingsManager.Default.GetOrCreate<PPCSettings>().DeploymentSlot, token)
{
}
public PPCWebClient() : this(null)
{
}
public PPCWebClient(string address, string token) : base(address, token)
{
}
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
{
/// <summary>
/// Represents the default <see cref="IMachineProvider"/>.
/// </summary>
/// <seealso cref="Tango.Core.ExtendedObject" />
/// <seealso cref="Tango.PPC.Common.Connection.IMachineProvider" />
public class DefaultMachineProvider : ExtendedObject, IMachineProvider
{
private bool _isInitialized;
private Thread _connection_thread;
private ObservablesContext _context;
private Machine _machine;
/// <summary>
/// Gets the database machine entity associated with the current machine.
/// </summary>
public Machine Machine
{
get
{
return _machine;
}
private set
{
_machine = value;
RaisePropertyChangedAuto();
}
}
private IMachineOperator _machineOperator;
/// <summary>
/// Gets the machine operator.
/// </summary>
public IMachineOperator MachineOperator
{
get
{
return _machineOperator;
}
private set
{
_machineOperator = value;
RaisePropertyChangedAuto();
}
}
/// <summary>
/// Initializes a new instance of the <see cref="DefaultMachineProvider"/> class.
/// </summary>
public DefaultMachineProvider()
{
var settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
MachineOperator = new MachineOperator();
MachineOperator.EnableEventsNotification = true;
MachineOperator.EnableJobResume = true;
MachineOperator.UseKeepAlive = true;
MachineOperator.EnableMachineStatusUpdates = true;
MachineOperator.EnableDiagnostics = true;
MachineOperator.EnableEmbeddedDebugging = settings.EnableEmbeddedDebugLogs;
MachineOperator.EnableAutomaticThreadLoading = settings.EnableAutomaticThreadLoading;
MachineOperator.JobRunsLogger.JobSource = BL.Enumerations.JobSource.Local;
MachineOperator.FirmwareUpgradeMode = Integration.Upgrade.FirmwareUpgradeModes.DFU | Integration.Upgrade.FirmwareUpgradeModes.TFP_PACKAGE;
MachineOperator.JobUploadStrategy = settings.JobUploadStrategy;
MachineOperator.JobUnitsMethod = settings.JobUnitsMethod;
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<PPCSettings>();
if (!Machine.IsDemo)
{
if (String.IsNullOrWhiteSpace(settings.EmbeddedComPort))
{
TimeSpan timeout = TimeSpan.FromSeconds(SettingsManager.Default.GetOrCreate<PPCSettings>().MachineScanningTimeoutSeconds);
LogManager.Log("Scanning for machine on available serial ports...", LogCategory.Debug);
Transport.Discovery.UsbCommunicationScanner<ConnectRequest, ConnectResponse> scanner = new Transport.Discovery.UsbCommunicationScanner<ConnectRequest, ConnectResponse>(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();
if (MachineOperator.DeviceInformation != null)
{
settings.FirmwareVersion = MachineOperator.DeviceInformation.Version;
settings.Save();
}
}
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();
if (MachineOperator.DeviceInformation != null)
{
settings.FirmwareVersion = MachineOperator.DeviceInformation.Version;
settings.Save();
}
}
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();
if (MachineOperator.DeviceInformation != null)
{
settings.FirmwareVersion = MachineOperator.DeviceInformation.Version;
settings.Save();
}
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);
}
}
/// <summary>
/// Initializes this machine provider start machine port scanning and connection.
/// </summary>
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 + ".");
if (Machine.IsDemo)
{
LogManager.Log("Machine is in demo mode. Changing firmware upgrade mode to TFP package only.");
MachineOperator.FirmwareUpgradeMode = Integration.Upgrade.FirmwareUpgradeModes.TFP_PACKAGE;
}
ConnectToMachine();
}
else
{
LogManager.Log("No machine entry found on database. Could not connect to the embedded device!", LogCategory.Error);
}
}
}
/// <summary>
/// Tries to connect to the machine by scanning all available serial ports.
/// The timeout for a scan cycle is specified on <see cref="PPCSettings.MachineScanningTimeoutSeconds"/>.
/// </summary>
private void ConnectToMachine()
{
if (_connection_thread == null)
{
_connection_thread = new Thread(ConnectionThreadMethod);
_connection_thread.IsBackground = true;
_connection_thread.Start();
}
}
/// <summary>
/// Saves the machine settings.
/// </summary>
/// <returns></returns>
public async Task SaveMachine()
{
await _context.SaveChangesAsync();
Machine = await new MachineBuilder(_context).SetFirst().BuildAsync();
TangoMessenger.Default.Send(new MachineSettingsSavedMessage() { Machine = Machine });
}
/// <summary>
/// Creates and connects a machine operator with no continuous requests at all.
/// </summary>
/// <returns></returns>
public static async Task<IMachineOperator> CreateMinimalMachineOperator(Action<String> 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<PPCSettings>();
if (String.IsNullOrWhiteSpace(settings.EmbeddedComPort))
{
TimeSpan timeout = TimeSpan.FromSeconds(SettingsManager.Default.GetOrCreate<PPCSettings>().MachineScanningTimeoutSeconds);
onProgress?.Invoke("Scanning for the machine...");
LogManager.Default.Log("Scanning for machine on available serial ports...");
Transport.Discovery.UsbCommunicationScanner<ConnectRequest, ConnectResponse> scanner = new Transport.Discovery.UsbCommunicationScanner<ConnectRequest, ConnectResponse>(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;
}
}
}