using Google.Protobuf;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.Transport.Servers;
using Tango.Logging;
using Tango.PMR;
using Tango.PMR.Common;
using Tango.PMR.Stubs;
using Tango.Core.Commands;
using Tango.Transport;
using Tango.PMR.Integration;
using Tango.PMR.Diagnostics;
using System.Windows.Forms;
using Google.Protobuf.Collections;
using Tango.PMR.Printing;
using Tango.BL.Entities;
using Tango.PMR.Debugging;
using Tango.BL.Enumerations;
using Tango.BL;
using Tango.PMR.Connection;
using Tango.PMR.Hardware;
using System.Runtime.InteropServices;
using Tango.PMR.IO;
using System.IO;
using Tango.Integration.Operation;
using Tango.PMR.FirmwareUpgrade;
using System.Diagnostics;
using Tango.Core.ExtensionMethods;
using Tango.PMR.MachineStatus;
using Tango.PMR.Power;
using Tango.PMR.ThreadLoading;
using Tango.PMR.IFS;
using Tango.PMR.DataStore;
using Tango.Core.Threading;
namespace Tango.Emulations.Emulators
{
///
/// Represents a Tango machine emulator.
///
///
public class MachineEmulator : EmulatorBase
{
[DllImport("Tango.Emulations.Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ProcessMessage")]
public static extern int ProcessMessageNative(IntPtr data, int size, ref IntPtr output);
private class ContinousResponseToken
{
public bool Canceled { get; set; }
}
private const int MAX_CHUNK_LENGTH = 4000;
private const int DIAGNOSTICS_INTERVAL = 300;
private static Random _rnd = new Random();
private StartDiagnosticsRequest _diagnosticsRequest;
private bool _cancelJob;
private List _motorJoggingRequestTypes;
private List _motorHomingRequestCodes;
private List _dispenserJoggingRequestCodes;
private List _dispenserHomingRequestCodes;
private double _graphAmplitude;
private double _graphFrequency;
private List _digitalOutputPinsStates;
private List _digitalInputPinsStates;
private List _componentsStates;
private List _heater_states;
private List _continousResponseTokens;
public List EventsStates { get; set; }
private bool _diagnostics_enabled;
private bool _debug_logs_enabled;
private bool _events_enabled;
private bool _machine_updates_enabled;
private List _blower_states;
private List _valveStates;
private JobTicket _current_job_ticket;
private String _current_job_resume_token;
private FileUploadRequest _lastFileUploadRequest;
private bool _isAfterReset;
private bool _abortPowerDown;
private bool _isThreadLoadingStarted;
private String _threadLoadingToken;
private DateTime _connectionTime;
private int _jobAbortCounter;
private bool _abortHeadCleaning;
private String _machineStatusRequestToken;
private MachineType _machineType;
private ProcessParameters _processParameters;
private bool _failJob;
private HardwareConfiguration _hardwareConfiguration;
#region Properties
private bool _performNativeRoundTrip;
///
/// Gets or sets a value indicating whether [perform native round trip].
///
public bool PerformNativeRoundTrip
{
get { return _performNativeRoundTrip; }
set { _performNativeRoundTrip = value; RaisePropertyChangedAuto(); }
}
private bool _emulateCorruption;
///
/// Gets or sets a value indicating whether emulate corruption in keep alive and job response.
///
public bool EmulateCorruption
{
get { return _emulateCorruption; }
set
{
_emulateCorruption = value;
RaisePropertyChangedAuto();
Transporter.EnableKeepAliveAutoResponse = !_emulateCorruption;
}
}
public MachineStatus MachineStatus { get; set; }
public InkFillingStatus InkFillingStatus { get; set; }
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
public MachineEmulator() : base()
{
Init();
}
///
/// Initializes a new instance of the class.
///
/// The transporter.
public MachineEmulator(ITransporter transporter) : base(transporter)
{
transporter.ComponentName = $"Machine Emulator";
LogManager.Log("Machine emulator initialized using transporter " + transporter.ToString());
Init();
}
#endregion
#region Private Methods
private ContinousResponseToken CreateCancelToken()
{
ContinousResponseToken t = new ContinousResponseToken();
_continousResponseTokens.Add(t);
return t;
}
private void Init()
{
_isAfterReset = true;
MachineStatus = new MachineStatus();
MachineStatus.SpoolState = SpoolState.Present;
MachineStatus.State = MachineState.Ready;
for (int i = 0; i < 4; i++)
{
if (i == 2)
{
MachineStatus.WindersInError.Add(false);
MachineStatus.DancersInError.Add(true);
MachineStatus.BtsrsInError.Add(true);
}
else
{
MachineStatus.WindersInError.Add(false);
MachineStatus.DancersInError.Add(false);
MachineStatus.BtsrsInError.Add(false);
}
}
EventsStates = MachineEventState.GetAllEventsStates();
_valveStates = new List();
_blower_states = new List();
_heater_states = new List();
_continousResponseTokens = new List();
_motorJoggingRequestTypes = new List();
_motorHomingRequestCodes = new List();
_dispenserJoggingRequestCodes = new List();
_dispenserHomingRequestCodes = new List();
_digitalOutputPinsStates = new List();
_componentsStates = new List();
ObservablesStaticCollections adapter = ObservablesStaticCollections.Instance;
adapter.Initialize();
_digitalOutputPinsStates = adapter.TechIos.Where(x => x.Type == IOType.DigitalOutput.ToInt32()).Select(x => new DigitalInterfaceState()
{
InterfaceIO = (InterfaceIOs)x.Code,
}).ToList();
_digitalInputPinsStates = adapter.TechIos.Where(x => x.Type == IOType.DigitalInput.ToInt32()).Select(x => new DigitalInterfaceState()
{
InterfaceIO = (InterfaceIOs)x.Code,
}).ToList();
foreach (var item in adapter.TechControllers)
{
_componentsStates.Add(new ValueComponentState()
{
Component = (ValueComponent)item.Code,
Value = item.Min
});
}
foreach (var item in adapter.TechHeaters)
{
_heater_states.Add(new HeaterState()
{
HeaterType = (HeaterType)item.Code,
});
}
var tunnel = _heater_states.FirstOrDefault(x => x.HeaterType == HeaterType.ETunnelHeater);
if (tunnel != null)
{
tunnel.IsRampingUp = true;
tunnel.CurrentValue = 108.5;
tunnel.SetPoint = 170;
}
var dryerZone1 = _heater_states.FirstOrDefault(x => x.HeaterType == HeaterType.EDryerHeater1);
if (dryerZone1 != null)
{
dryerZone1.IsRampingUp = false;
dryerZone1.CurrentValue = 0;
dryerZone1.SetPoint = 200;
}
var dryerZone2 = _heater_states.FirstOrDefault(x => x.HeaterType == HeaterType.EDryerHeater2);
if (dryerZone2 != null)
{
dryerZone2.IsRampingUp = false;
dryerZone2.CurrentValue = 0;
dryerZone2.SetPoint = 200;
}
var dryerZone3 = _heater_states.FirstOrDefault(x => x.HeaterType == HeaterType.EDryerHeater3);
if (dryerZone3 != null)
{
dryerZone3.IsRampingUp = false;
dryerZone3.CurrentValue = 0;
dryerZone3.SetPoint = 200;
}
//DryerZone3
foreach (var item in adapter.HardwareBlowerTypes)
{
_blower_states.Add(new SetBlowerStateRequest()
{
BlowerType = (PMR.Hardware.HardwareBlowerType)item.Code,
});
}
foreach (var item in adapter.TechValves)
{
_valveStates.Add(new ValveState()
{
ValveType = (ValveType)item.Code,
State = (ValveStateCode)Enum.Parse(typeof(ValveStateCode), item.State1.Replace(" ", ""), true),
});
}
ResetGraphFactors();
InkFillingStatus = new InkFillingStatus();
for (int i = 0; i < 8; i++)
{
InkFillingStatus.CartridgesStatuses.Add(new CartridgeStatus()
{
Cartridge = new Cartridge()
{
Index = i,
Slot = CartridgeSlot.Ink,
},
State = CartridgeState.Present,
Message = "This is an emulated ink filling message"
});
}
InkFillingStatus.CartridgesStatuses.Add(new CartridgeStatus()
{
Cartridge = new Cartridge() { Index = 0, Slot = CartridgeSlot.WasteMiddle },
State = CartridgeState.Present,
Message = "This is an emulated waste emptying message"
});
InkFillingStatus.CartridgesStatuses.Add(new CartridgeStatus()
{
Cartridge = new Cartridge() { Index = 1, Slot = CartridgeSlot.WasteLower },
State = CartridgeState.Present,
Message = "This is an emulated waste emptying message"
});
}
private void ResetGraphFactors()
{
_graphAmplitude = 75;
_graphFrequency = 1;
}
#endregion
#region Override Methods
public override Task Start()
{
_current_job_resume_token = null;
_isAfterReset = true;
return base.Start();
}
///
/// Called on new request message.
///
/// The sender.
/// The container.
protected override void OnTransporterRequestReceived(object sender, RequestReceivedEventArgs e)
{
var container = e.Container;
if (container.Type != MessageType.FileChunkUploadRequest && container.Type != MessageType.FileChunkDownloadRequest)
{
LogManager.Log(container.Type.ToString().ToWords() + " received." + Environment.NewLine + MessageFactory.ExtractMessageFromContainer(container).ToJsonString());
}
if (PerformNativeRoundTrip)
{
NativePMR nativePMR = new NativePMR(ProcessMessageNative);
var response = nativePMR.Invoke(container);
if (response != null)
{
container = response;
}
else
{
LogManager.Log("Native RoundTrip is not available for " + container.Type.ToString() + ".");
}
}
switch (container.Type)
{
case MessageType.CalculateRequest:
HandleCalculateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ProgressRequest:
HandleProgressRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartDiagnosticsRequest:
HandleStartDiagnosticsRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StopDiagnosticsRequest:
HandleStopDiagnosticsRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartEventsNotificationRequest:
HandleStartEventsNotificationRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StopEventsNotificationRequest:
HandleStopEventsNotificationRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartMachineStatusUpdateRequest:
HandleStartMachineStatusUpdateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StopMachineStatusUpdateRequest:
HandleStopMachineStatusUpdateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.JobRequest:
HandleJobRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.AbortJobRequest:
HandleAbortJobRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.MotorJoggingRequest:
HandleMotorJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.MotorAbortJoggingRequest:
HandleAbortMotorJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.MotorHomingRequest:
HandleMotorHomingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.MotorAbortHomingRequest:
HandleAbortMotorHomingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DispenserJoggingRequest:
HandleDispenserJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DispenserAbortJoggingRequest:
HandleAbortDispenserJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DispenserHomingRequest:
HandleDispenserHomingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DispenserAbortHomingRequest:
HandleAbortDispenserHomingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SetDigitalOutRequest:
HandleSetDigitalOutRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ThreadJoggingRequest:
HandleThreadJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ThreadAbortJoggingRequest:
HandleThreadAbortJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartDebugLogRequest:
HandleStartDebugLogRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StopDebugLogRequest:
HandleStopDebugLogRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.UploadProcessParametersRequest:
HandleUploadProcessParametersRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SetComponentValueRequest:
HandleSetComponentValueRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ResolveEventRequest:
HandleResolveEventRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DisconnectRequest:
HandleDisconnectRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ConnectRequest:
HandleConnectRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.UploadHardwareConfigurationRequest:
HandleUploadHardwareConfigurationRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StubFpgaWriteRegRequest:
HandleResetRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SetHeaterStateRequest:
HandleSetHeaterStateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SetBlowerStateRequest:
HandleSetBlowerStateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SetValveStateRequest:
HandleSetValveStateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.CurrentJobRequest:
HandleCurrentJobRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ResumeCurrentJobRequest:
HandleResumeCurrentJobRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.GetStorageInfoRequest:
HandleGetStorageInfoRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.GetFilesRequest:
HandleGetFilesRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.FileDownloadRequest:
HandleFileDownloadRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.FileChunkDownloadRequest:
HandleFileChunkDownloadRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.CreateRequest:
HandleCreateRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DeleteRequest:
HandleDeleteRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.FileUploadRequest:
HandleFileUploadRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.FileChunkUploadRequest:
HandleFileChunkUploadRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ValidateVersionRequest:
HandleValidateVersionRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ActivateVersionRequest:
HandleActivateVersionRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartPowerDownRequest:
HandleStartPowerDownRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.AbortPowerDownRequest:
HandleAbortPowerDownRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartThreadLoadingRequest:
HandleStartThreadLoadingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.AbortThreadLoadingRequest:
HandleAbortThreadLoadingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.TryThreadLoadingRequest:
HandleTryThreadLoadingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.ContinueThreadLoadingRequest:
HandleContinueThreadLoadingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartHeadCleaningRequest:
HandleStartHeadCleaningRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.AbortHeadCleaningRequest:
HandleAbortHeadCleaningRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartPowerUpRequest:
HandleStartPowerUpRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StartInkFillingStatusRequest:
HandleStartInkFillingStatusRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.StandByRequest:
HandleStandByRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.AttemptThreadJoggingRequest:
HandleAttemptThreadJoggingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.DataStoreItemModifiedRequest:
HandleDataStoreItemModifiedRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.JobPrepareRequest:
HandleJobPrepareRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SetInkAutoFillingModeRequest:
HandleSetInkAutoFillingModeRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.BitResultsRequest:
HandleBitResultsRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.SpoolTypeChangedRequest:
HandleSpoolTypeChangedRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.InitiateInkFillingRequest:
HandleInitiateInkFillingRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
case MessageType.GetVersionDescriptorsRequest:
HandleGetVersionDescriptorsRequest(MessageFactory.ParseTangoMessageFromContainer(container));
break;
}
}
#endregion
#region Request Handlers
private void HandleAbortThreadLoadingRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
Transporter.SendResponse(new AbortThreadLoadingResponse(), request.Container.Token);
});
}
private void HandleCalculateRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
var response = MessageFactory.CreateTangoMessage(request.Container.Token);
response.Message.Sum = request.Message.A + request.Message.B;
Transporter.SendResponse(response);
});
}
private void HandleProgressRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
for (int i = 0; i < request.Message.Amount; i++)
{
Thread.Sleep(request.Message.Delay);
var res = MessageFactory.CreateTangoMessage(request.Container.Token);
res.Message.Progress = i;
if (i == request.Message.Amount - 1) res.Container.Completed = true;
Transporter.SendResponse(res);
}
Transporter.SendResponse(new ProgressResponse(), request.Container.Token, new TransportResponseConfig() { Completed = true });
});
}
private void HandleStartDiagnosticsRequest(TangoMessage request)
{
_diagnostics_enabled = true;
_diagnosticsRequest = request.Message;
int value = 0;
Random rnd = new Random();
int airDryer = 0;
int dryerTarget = _processParameters != null ? (int)_processParameters.ESpare1 : 200;
var cancelToken = CreateCancelToken();
Stopwatch watch = new Stopwatch();
Task.Factory.StartNew(() =>
{
watch.Start();
while (_diagnostics_enabled && Transporter.State == TransportComponentState.Connected && !cancelToken.Canceled)
{
StartDiagnosticsResponse res = new StartDiagnosticsResponse();
DiagnosticsMonitors monitors = new DiagnosticsMonitors();
res.Monitors = monitors;
if (airDryer < dryerTarget)
{
airDryer++;
}
else
{
airDryer = 0;
}
res.Monitors.EuSpare1.Add(airDryer);
for (int i = 0; i < 10; i++)
{
value++;
monitors.Dancer1Angle.Add((int)(150 + _graphAmplitude * Math.Sin(2 * 3.14 * ((int)_graphFrequency) * value)));
}
var blower_state = _blower_states.FirstOrDefault();
if (blower_state != null)
{
monitors.BlowerVoltage.Add(blower_state.IsActive ? blower_state.Voltage : 0);
}
int y = Cursor.Position.Y;
for (int i = 0; i < 1; i++)
{
monitors.Dancer2Angle.Add(y);
monitors.GasSensor.Add(y);
monitors.FilterDeltaPressure.Add(y);
}
for (int i = 0; i < 30; i++)
{
monitors.Dancer3Angle.Add(y);
}
for (int i = 0; i < MachineStatus.IDSPacksLevels.Count; i++)
{
var dispensers = new DoubleArray();
dispensers.Data.Add(MachineStatus.IDSPacksLevels[i].DispenserLevel);
monitors.DispensersInkLevel.Add(dispensers);
var midTanks = new DoubleArray();
midTanks.Data.Add(MachineStatus.IDSPacksLevels[i].MidTankLevel);
monitors.MidTanksInkLevel.Add(midTanks);
}
var dispenserFrequencies = new RepeatedField();
double cPosition = Cursor.Position.Y;
for (int i = 0; i < 8; i++)
{
DoubleArray singleDispenser = new DoubleArray();
for (int j = 0; j < 10; j++)
{
singleDispenser.Data.Add(cPosition + (i * 50));
}
dispenserFrequencies.Add(singleDispenser);
}
monitors.DispensersMotorsFrequency.AddRange(dispenserFrequencies);
monitors.Dispenser1MotorFrequency.AddRange(dispenserFrequencies[0].Data);
monitors.Dispenser2MotorFrequency.AddRange(dispenserFrequencies[1].Data);
monitors.Dispenser3MotorFrequency.AddRange(dispenserFrequencies[2].Data);
monitors.Dispenser4MotorFrequency.AddRange(dispenserFrequencies[3].Data);
monitors.Dispenser5MotorFrequency.AddRange(dispenserFrequencies[4].Data);
monitors.Dispenser6MotorFrequency.AddRange(dispenserFrequencies[5].Data);
monitors.Dispenser7MotorFrequency.AddRange(dispenserFrequencies[6].Data);
monitors.Dispenser8MotorFrequency.AddRange(dispenserFrequencies[7].Data);
monitors.EuDispenser1Pressure.Clear();
monitors.EuDispenser1Pressure.Add(5);
monitors.EuLubricantCurrent.Add(4000.12345);
//res.HeatersStates.Add(new HeaterState()
//{
// CurrentValue = 50,
// IsInSetPoint = false,
// SetPoint = 100
//});
res.DigitalInterfaceStates.AddRange(_digitalOutputPinsStates.Concat(_digitalInputPinsStates));
res.ComponentsStates.AddRange(_componentsStates);
res.HeatersStates.AddRange(_heater_states);
res.ValvesStates.AddRange(_valveStates);
res.ElapsedMilli = (uint)watch.ElapsedMilliseconds;
watch.Restart();
if (!EmulateCorruption)
{
Transporter.SendResponse(res, request.Container.Token);
}
Thread.Sleep(DIAGNOSTICS_INTERVAL);
}
});
}
private void HandleStopDiagnosticsRequest(TangoMessage request)
{
_diagnostics_enabled = false;
Transporter.SendResponse(new StopDiagnosticsResponse(), request.Container.Token);
}
private void HandleStartEventsNotificationRequest(TangoMessage request)
{
_events_enabled = true;
var cancelToken = CreateCancelToken();
Task.Factory.StartNew(() =>
{
while (_events_enabled && Transporter.State == TransportComponentState.Connected && !cancelToken.Canceled)
{
var res = new StartEventsNotificationResponse();
res.Events.AddRange(EventsStates.Where(x => x.IsActive).Select(x => new Event() { Type = x.EventType, Message = "Generated by Tango Embedded Emulator" }));
if (!EmulateCorruption)
{
Transporter.SendResponse(res, request.Container.Token);
}
Thread.Sleep(1000);
}
});
}
private void HandleStopEventsNotificationRequest(TangoMessage request)
{
_events_enabled = false;
Transporter.SendResponse(new StopEventsNotificationResponse(), request.Container.Token);
}
private void HandleStartMachineStatusUpdateRequest(TangoMessage request)
{
_machine_updates_enabled = true;
var cancelToken = CreateCancelToken();
_machineStatusRequestToken = request.Container.Token;
Task.Factory.StartNew(() =>
{
while (_machine_updates_enabled && Transporter.State == TransportComponentState.Connected && !cancelToken.Canceled)
{
var res = new StartMachineStatusUpdateResponse();
res.Status = MachineStatus;
res.Status.OverallTemperature = Cursor.Position.Y;
if (!EmulateCorruption && _hardwareConfiguration != null)
{
Transporter.SendResponse(res, request.Container.Token);
}
Thread.Sleep(1000);
}
});
}
private void HandleStopMachineStatusUpdateRequest(TangoMessage request)
{
_machine_updates_enabled = false;
Transporter.SendResponse(new StopMachineStatusUpdateResponse(), request.Container.Token);
}
private void HandleStartDebugLogRequest(TangoMessage request)
{
_debug_logs_enabled = true;
int counter = 1;
int counter_message = 0;
var cancelToken = CreateCancelToken();
Task.Factory.StartNew(() =>
{
while (_debug_logs_enabled && Transporter.State == TransportComponentState.Connected && !cancelToken.Canceled)
{
StartDebugLogResponse res = new StartDebugLogResponse();
res.FileName = "C:\\demoFile.c";
res.LineNumber = 100;
res.Filter = 1;
res.Message = "This is a false message " + counter;
res.Category = DebugLogCategory.Error;
if (!EmulateCorruption)
{
Transporter.SendResponse(res, request.Container.Token);
}
Thread.Sleep(1000);
counter_message++;
if (counter_message > 10)
{
counter_message = 0;
counter++;
}
}
});
}
private void HandleJobRequest(TangoMessage request)
{
_failJob = false;
MachineStatus.State = MachineState.PreparingJob;
JobTicket job = request.Message.JobTicket;
var jobTicket = job;
_current_job_ticket = jobTicket.Clone();
_current_job_resume_token = null;
if (jobTicket.UploadStrategy == JobUploadStrategy.JobDescriptionFile)
{
using (FileStream fs = new FileStream(jobTicket.JobDescriptionFile, FileMode.Open))
{
var segments = JobDescriptionFile.ReadJobDescriptionFile(fs);
jobTicket.Segments.AddRange(segments);
}
var logedTicket = jobTicket.Clone();
foreach (var segment in logedTicket.Segments)
{
if (segment.BrushStops.Count > 2)
{
var first = segment.BrushStops.First();
var last = segment.BrushStops.Last();
segment.BrushStops.Clear();
segment.BrushStops.Add(first);
segment.BrushStops.Add(last);
}
}
LogManager.Log("Parsed Job Upload File (Showing first and last brush stop for segment):\n" + logedTicket.ToJsonString());
}
double centimeter_per_second = request.Message.JobTicket.ProcessParameters.DyeingSpeed;
_cancelJob = false;
bool message_sent = false;
int units = (int)Math.Max(job.NumberOfUnits, 1);
double unit_length = job.Length;/// units;
Task.Factory.StartNew(() =>
{
MachineStatus.State = MachineState.RunningJob;
List calculatedStopIndexes = new List();
double progress = 0;
double lastProgress = 0;
Stopwatch watch = new Stopwatch();
Dictionary dispenserindexToPacklevel = new Dictionary();
double dryerLength = _machineType == MachineType.Ts1800 ? (job.ProcessParameters.DryerBufferLength * ProcessParametersTable.DRYER_METERS_PER_CYCLE + ProcessParametersTable.DRYER_TO_SPOOL_LENGTH_METERS) : job.ProcessParameters.DryerBufferLength;
//TODO Handle First Unit Length Decrease In Emulator!
double firstUnitStartPosition = request.Message.FirstUnitStartPosition;
bool addedResume = firstUnitStartPosition <= 0;
//bool bIsResumeProcess = firstUnitStartPosition > 0;
for (int i = 0; i < units; i++)
{
// while (progress < unit_length + (!bIsResumeProcess && i == units - 1 ? dryerLength : 0) && !_cancelJob)
while (progress < unit_length + (i == units - 1 ? dryerLength : 0) && !_cancelJob)
{
var status = new PMR.Printing.JobStatus();
status.Progress = progress;
if (!message_sent)
{
message_sent = true;
status.Message = "Demo Message From Emulator...";
}
if (!EmulateCorruption)
{
if (_current_job_resume_token == null)
{
Transporter.SendResponse(new JobResponse()
{
Status = status,
}, request.Container.Token);
}
else
{
Transporter.SendResponse(new ResumeCurrentJobResponse()
{
Status = status,
}, _current_job_resume_token);
}
}
else
{
LogManager.Log($"[Machine Enulator]: Job Progress: {progress}");
}
if (addedResume)
{
progress += Math.Min((centimeter_per_second / 1000d), (unit_length + (i == units - 1 ? dryerLength : 0)) - progress);
}
else
{
addedResume = true;
progress = firstUnitStartPosition;
}
//LogManager.Log($" EMULATOR PROGRESS Progress = {progress}, units = {units}");
double currentPosition = 0;
double nextStopPosition = unit_length;
watch.Restart();
for (int seg_index = 0; seg_index < jobTicket.Segments.Count(); seg_index++)
{
var segment = jobTicket.Segments[seg_index];
if ((seg_index + 1) < jobTicket.Segments.Count())
{
nextStopPosition = jobTicket.Segments[seg_index + 1].Length;
}
calculatedStopIndexes = new List();
for (int index = 0; index < segment.BrushStops.Count(); index++)
{
var stop = segment.BrushStops[index];
if ((index + 1) < segment.BrushStops.Count())
{
var nextStop = segment.BrushStops[index + 1];
nextStopPosition = nextStop.OffsetMeters;
}
if (!calculatedStopIndexes.Contains(stop.Index))
{
var brushStopPosition = currentPosition + stop.OffsetMeters;
if (brushStopPosition >= lastProgress && brushStopPosition <= progress)
{
foreach (var dispenser in stop.Dispensers)
{
var quantity = dispenser.NanoliterPerCentimeter * (nextStopPosition - stop.OffsetMeters) * 100d;
IDSPackLevel packLevel;
if (!dispenserindexToPacklevel.TryGetValue(dispenser.Index, out packLevel))
{
packLevel = MachineStatus.IDSPacksLevels.SingleOrDefault(x => x.Index == dispenser.Index);
dispenserindexToPacklevel.Add(dispenser.Index, packLevel);
}
if (packLevel != null)
{
packLevel.DispenserLevel -= (int)quantity;
}
}
calculatedStopIndexes.Add(stop.Index);
}
}
}
currentPosition += segment.Length;
}
watch.Stop();
lastProgress = progress;
int delay = (100 - (int)watch.ElapsedMilliseconds) > 0 ? (100 - (int)watch.ElapsedMilliseconds) : 5;
Thread.Sleep(delay);
if (_failJob)
{
if (_current_job_resume_token == null)
{
Transporter.SendResponse(new JobResponse()
{
}, request.Container.Token, new TransportResponseConfig()
{
ErrorCode = ErrorCode.JobThreadBreak,
ErrorMessage = "This is a message about a thread break from the emulator",
EventType = PMR.Diagnostics.EventType.ThreadBreak,
});
}
else
{
Transporter.SendResponse(new CurrentJobResponse()
{
}, request.Container.Token, new TransportResponseConfig()
{
ErrorCode = ErrorCode.JobThreadBreak,
ErrorMessage = "This is a message about a thread break from the emulator",
EventType = PMR.Diagnostics.EventType.ThreadBreak,
});
}
break;
}
if (_cancelJob)
{
_current_job_resume_token = null;
break;
}
}
if (_cancelJob)
{
_current_job_resume_token = null;
break;
}
}
foreach (var packLevel in MachineStatus.IDSPacksLevels)
{
Debug.WriteLine($"Emulator: Pack Index = {packLevel.Index}");
Debug.WriteLine($"Emulator: Quantity = {MachineOperator.MAX_DISPENSER_NANOLITER - packLevel.DispenserLevel}");
}
jobTicket = null;
if (_cancelJob)
{
if (_current_job_resume_token == null)
{
Transporter.SendResponse(new JobResponse()
{
}, request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.ContinuousResponseAborted });
}
else
{
Transporter.SendResponse(new ResumeCurrentJobResponse()
{
}, _current_job_resume_token, new TransportResponseConfig() { ErrorCode = ErrorCode.ContinuousResponseAborted });
}
}
else
{
if (_current_job_resume_token == null)
{
Transporter.SendResponse(new JobResponse()
{
Status = new PMR.Printing.JobStatus()
{
Progress = unit_length + dryerLength,
}
}, request.Container.Token, new TransportResponseConfig() { Completed = !_cancelJob });
if (_rnd.Next(0, 100) > 50)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
MachineStatus.SpoolState = SpoolState.Absent;
Transporter.SendResponse(new StartMachineStatusUpdateResponse() { Status = MachineStatus }, _machineStatusRequestToken);
Thread.Sleep(2000);
MachineStatus.SpoolState = SpoolState.Present;
Transporter.SendResponse(new StartMachineStatusUpdateResponse() { Status = MachineStatus }, _machineStatusRequestToken);
});
}
}
else
{
Transporter.SendResponse(new ResumeCurrentJobResponse()
{
Status = new PMR.Printing.JobStatus()
{
Progress = unit_length + dryerLength,
}
}, _current_job_resume_token, new TransportResponseConfig() { Completed = !_cancelJob });
}
}
MachineStatus.State = MachineState.Ready;
});
}
private void HandleAbortJobRequest(TangoMessage request)
{
//if (_jobAbortCounter == 1)
//{
_cancelJob = true;
Transporter.SendResponse(new AbortJobResponse(), request.Container.Token);
// _jobAbortCounter = 0;
//}
//else
//{
// _jobAbortCounter++;
//}
}
private void HandleMotorJoggingRequest(TangoMessage request)
{
var jogRequest = request.Message;
_motorJoggingRequestTypes.Add(jogRequest.MotorType);
Task.Factory.StartNew(() =>
{
while (_motorJoggingRequestTypes.Contains(jogRequest.MotorType))
{
if (jogRequest.Direction == MotorDirection.Forward)
{
_graphFrequency = 10;
}
else
{
_graphFrequency = 18;
}
Thread.Sleep(30);
}
ResetGraphFactors();
});
Transporter.SendResponse(new MotorJoggingResponse(), request.Container.Token);
}
private void HandleAbortMotorJoggingRequest(TangoMessage request)
{
_motorJoggingRequestTypes.RemoveAll(x => x == request.Message.MotorType);
ResetGraphFactors();
Transporter.SendResponse(new MotorAbortJoggingResponse(), request.Container.Token);
}
private void HandleMotorHomingRequest(TangoMessage request)
{
var homeRequest = request.Message;
_motorHomingRequestCodes.Add(homeRequest.MotorType);
Task.Factory.StartNew(() =>
{
_graphFrequency = 10;
var inputPin = _digitalInputPinsStates.FirstOrDefault();
for (int i = 0; i < 100; i++)
{
if (inputPin != null)
{
inputPin.Value = !inputPin.Value;
}
Transporter.SendResponse(new MotorHomingResponse() { MaxProgress = 100, Progress = i }, request.Container.Token);
if (!_motorHomingRequestCodes.Contains(homeRequest.MotorType))
{
ResetGraphFactors();
return;
}
Thread.Sleep(30);
}
Transporter.SendResponse(new MotorHomingResponse() { MaxProgress = 100, Progress = 100 }, request.Container.Token, new TransportResponseConfig() { Completed = true });
_motorHomingRequestCodes.Remove(homeRequest.MotorType);
ResetGraphFactors();
if (request.Message.MotorType == PMR.Hardware.HardwareMotorType.MotoDhLid)
{
if (request.Message.Direction == MotorDirection.Backward)
{
var eventState1 = EventsStates.FirstOrDefault(x => x.EventType == PMR.Diagnostics.EventType.DyeingHeadArcLidIsOpen);
var eventState2 = EventsStates.FirstOrDefault(x => x.EventType == PMR.Diagnostics.EventType.DyeingHeadCoverIsOpen);
eventState1.IsActive = true;
eventState2.IsActive = true;
}
else
{
var eventState1 = EventsStates.FirstOrDefault(x => x.EventType == PMR.Diagnostics.EventType.DyeingHeadArcLidIsOpen);
var eventState2 = EventsStates.FirstOrDefault(x => x.EventType == PMR.Diagnostics.EventType.DyeingHeadCoverIsOpen);
eventState1.IsActive = false;
eventState2.IsActive = false;
}
}
});
}
private void HandleAbortMotorHomingRequest(TangoMessage request)
{
_motorHomingRequestCodes.RemoveAll(x => x == request.Message.MotorType);
ResetGraphFactors();
Transporter.SendResponse(new MotorAbortHomingResponse(), request.Container.Token);
}
private void HandleDispenserJoggingRequest(TangoMessage request)
{
var jogRequest = request.Message;
_dispenserJoggingRequestCodes.Add(jogRequest.Index);
Task.Factory.StartNew(() =>
{
while (_dispenserJoggingRequestCodes.Contains(jogRequest.Index))
{
if (jogRequest.Direction == MotorDirection.Forward)
{
_graphFrequency = 10;
}
else
{
_graphFrequency = 18;
}
Thread.Sleep(30);
}
ResetGraphFactors();
});
Transporter.SendResponse(new DispenserJoggingResponse(), request.Container.Token);
}
private void HandleAbortDispenserJoggingRequest(TangoMessage request)
{
_dispenserJoggingRequestCodes.RemoveAll(x => x == request.Message.Index);
ResetGraphFactors();
Transporter.SendResponse(new DispenserAbortJoggingResponse(), request.Container.Token);
}
private void HandleDispenserHomingRequest(TangoMessage request)
{
var homeRequest = request.Message;
_dispenserHomingRequestCodes.Add(homeRequest.Index);
Task.Factory.StartNew(() =>
{
_graphFrequency = 10;
for (int i = 0; i < 100; i++)
{
Transporter.SendResponse(new DispenserHomingResponse() { MaxProgress = 100, Progress = i }, request.Container.Token);
if (!_dispenserHomingRequestCodes.Contains(homeRequest.Index))
{
ResetGraphFactors();
return;
}
Thread.Sleep(30);
}
Transporter.SendResponse(new DispenserHomingResponse() { MaxProgress = 100, Progress = 100 }, request.Container.Token, new TransportResponseConfig() { Completed = true });
_dispenserHomingRequestCodes.Remove(homeRequest.Index);
ResetGraphFactors();
});
}
private void HandleAbortDispenserHomingRequest(TangoMessage request)
{
_dispenserHomingRequestCodes.RemoveAll(x => x == request.Message.Index);
ResetGraphFactors();
Transporter.SendResponse(new DispenserAbortHomingResponse(), request.Container.Token);
}
private void HandleSetDigitalOutRequest(TangoMessage request)
{
var pinState = _digitalOutputPinsStates.SingleOrDefault(x => x.InterfaceIO == request.Message.InterfaceIO);
if (pinState != null)
{
pinState.Value = request.Message.Value;
Transporter.SendResponse(new SetDigitalOutResponse(), request.Container.Token);
}
else
{
Transporter.SendResponse(new SetDigitalOutResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.InvalidDigitalPinNumber });
}
}
private void HandleThreadJoggingRequest(TangoMessage request)
{
Transporter.SendResponse(new ThreadJoggingResponse(), request.Container.Token);
}
private void HandleThreadAbortJoggingRequest(TangoMessage request)
{
Transporter.SendResponse(new ThreadAbortJoggingResponse(), request.Container.Token);
}
private void HandleUploadProcessParametersRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
_processParameters = request.Message.ProcessParameters;
Thread.Sleep(1000);
Transporter.SendResponse(new UploadProcessParametersResponse(), request.Container.Token);
});
}
private void HandleSetComponentValueRequest(TangoMessage request)
{
var componentState = _componentsStates.SingleOrDefault(x => x.Component == request.Message.Component);
double startValue = componentState.Value;
double targetValue = request.Message.Value;
Transporter.SendResponse(new SetComponentValueResponse(), request.Container.Token);
Task.Factory.StartNew(() =>
{
if (targetValue > startValue)
{
while (componentState.Value < targetValue)
{
componentState.Value++;
Thread.Sleep(30);
}
}
else
{
while (componentState.Value > targetValue)
{
componentState.Value--;
Thread.Sleep(30);
}
}
});
}
private void HandleResolveEventRequest(TangoMessage request)
{
EventsStates.Where(x => x.EventType == request.Message.Type).ToList().ForEach(x => x.IsActive = false);
Transporter.SendResponse(new ResolveEventResponse(), request.Container.Token);
}
private void HandleDisconnectRequest(TangoMessage request)
{
foreach (var cancelToken in _continousResponseTokens)
{
cancelToken.Canceled = true;
}
_continousResponseTokens.Clear();
try
{
Transporter.SendResponse(new DisconnectResponse(), request.Container.Token);
}
catch { }
}
private void HandleConnectRequest(TangoMessage request)
{
if (!EmulateCorruption)
{
foreach (var cancelToken in _continousResponseTokens)
{
cancelToken.Canceled = true;
}
_continousResponseTokens.Clear();
Transporter.SendResponse(new ConnectResponse()
{
DeviceInformation = new DeviceInformation()
{
Version = "1.0.0.0",
BuildDate = DateTime.Now.ToString(),
Name = "Machine Emulator",
FPGA1Version = "1.1",
FPGA2Version = "2.2",
FPGA3Version = "3.3",
DiagnosticsInterval = (uint)DIAGNOSTICS_INTERVAL,
HeadType = HeadType.Arc,
},
IsAfterReset = _isAfterReset,
}, request.Container.Token, new TransportResponseConfig() { ErrorCode = request.Message.Password == "1234" ? ErrorCode.None : ErrorCode.UnauthorizedConnection });
_machineType = request.Message.MachineType;
_connectionTime = DateTime.Now;
_isAfterReset = false;
}
}
private void HandleStopDebugLogRequest(TangoMessage request)
{
_debug_logs_enabled = false;
Transporter.SendResponse(new StopDebugLogResponse(), request.Container.Token);
}
private void HandleUploadHardwareConfigurationRequest(TangoMessage request)
{
_hardwareConfiguration = request.Message.HardwareConfiguration;
int dispenserCount = _hardwareConfiguration != null ? _hardwareConfiguration.Dispensers.Count : 10;
for (int i = 0; i < dispenserCount; i++)
{
MachineStatus.IDSPacksLevels.Add(new IDSPackLevel()
{
Index = i,
DispenserLevel = 130000000,
MidTankLevel = 2.5,
});
}
Transporter.SendResponse(new UploadHardwareConfigurationResponse(), request.Container.Token);
}
private void HandleResetRequest(TangoMessage request)
{
Transporter.SendResponse(new StubFpgaWriteRegResponse(), request.Container.Token);
}
private void HandleSetHeaterStateRequest(TangoMessage request)
{
var heater = _heater_states.SingleOrDefault(x => x.HeaterType == request.Message.HeaterType);
if (heater != null)
{
double startValue = heater.CurrentValue;
double targetValue = request.Message.SetPoint;
Task.Factory.StartNew(() =>
{
heater.IsRampingUp = true;
heater.IsActive = true;
heater.IsInSetPoint = false;
heater.SetPoint = targetValue;
if (targetValue > startValue)
{
while (heater.CurrentValue < targetValue)
{
heater.CurrentValue++;
Thread.Sleep(30);
}
}
else
{
while (heater.CurrentValue > targetValue)
{
heater.CurrentValue--;
Thread.Sleep(30);
}
}
heater.IsRampingUp = false;
heater.IsActive = false;
heater.IsInSetPoint = true;
});
}
Transporter.SendResponse(new SetHeaterStateResponse(), request.Container.Token);
}
private void HandleSetBlowerStateRequest(TangoMessage request)
{
var blower_state = _blower_states.FirstOrDefault();
if (blower_state != null)
{
blower_state.Voltage = request.Message.Voltage;
blower_state.IsActive = request.Message.IsActive;
}
Transporter.SendResponse(new SetBlowerStateResponse(), request.Container.Token);
}
private void HandleSetValveStateRequest(TangoMessage request)
{
var valve_state = _valveStates.SingleOrDefault(x => x.ValveType == request.Message.ValveType);
if (valve_state != null)
{
valve_state.State = request.Message.State;
}
Transporter.SendResponse(new SetValveStateResponse(), request.Container.Token);
}
private void HandleCurrentJobRequest(TangoMessage request)
{
Transporter.SendResponse(new CurrentJobResponse()
{
IsJobInProgress = _current_job_ticket != null,
JobTicket = _current_job_ticket,
}, request.Container.Token);
}
private void HandleResumeCurrentJobRequest(TangoMessage request)
{
if (_current_job_ticket != null)
{
_current_job_resume_token = request.Container.Token;
}
else
{
Transporter.SendResponse(new ResumeCurrentJobResponse(), request.Container.Token, new TransportResponseConfig() { Completed = true, ErrorCode = ErrorCode.NoJobInProgress });
}
}
private void HandleGetStorageInfoRequest(TangoMessage request)
{
var d = new DriveInfo("C");
Directory.CreateDirectory("C:\\EmulatorStorage");
Transporter.SendResponse(new GetStorageInfoResponse()
{
Capacity = d.TotalSize,
FreeSpace = d.TotalFreeSpace,
Root = "C:\\EmulatorStorage"
}, request.Container.Token);
}
private void HandleGetFilesRequest(TangoMessage request)
{
GetFilesResponse response = new GetFilesResponse();
bool failed = false;
String msg = null;
try
{
String path = request.Message.Path;
bool replaceSlash = path.Contains("/");
foreach (var dir in Directory.GetDirectories(path))
{
DirectoryInfo dirInfo = new DirectoryInfo(dir);
response.Items.Add(new PMR.IO.FileInfo()
{
Attribute = FileAttribute.Directory,
FullPath = replaceSlash ? dir.Replace("\\", "/") : dir,
LastModifiedDate = dirInfo.LastWriteTime.DayOfYear,
LastModifiedTime = dirInfo.LastWriteTime.Hour,
Name = Path.GetFileName(dir),
});
}
foreach (var file in Directory.GetFiles(path))
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(file);
response.Items.Add(new PMR.IO.FileInfo()
{
Attribute = FileAttribute.Unspecified,
FullPath = replaceSlash ? file.Replace("\\", "/") : file,
LastModifiedDate = fileInfo.LastWriteTime.DayOfYear,
LastModifiedTime = fileInfo.LastWriteTime.Hour,
Name = Path.GetFileName(file),
Length = (int)fileInfo.Length,
});
}
}
catch (Exception ex)
{
failed = true;
msg = ex.Message;
}
Transporter.SendResponse(response, request.Container.Token, new TransportResponseConfig() { ErrorCode = failed ? ErrorCode.GeneralError : ErrorCode.None, ErrorMessage = msg });
}
private void HandleFileDownloadRequest(TangoMessage request)
{
long length = File.Exists(request.Message.FileName) ? new System.IO.FileInfo(request.Message.FileName).Length : 0;
Transporter.SendResponse(new FileDownloadResponse()
{
DownloadID = Guid.NewGuid().ToString(),
MaxChunkLength = Math.Min(MAX_CHUNK_LENGTH, length),
}, request.Container.Token, new TransportResponseConfig() { ErrorCode = File.Exists(request.Message.FileName) ? ErrorCode.None : ErrorCode.FileNotFound });
}
private void HandleFileChunkDownloadRequest(TangoMessage request)
{
var message = request.Message;
try
{
using (FileStream fs = new FileStream(message.FileName, FileMode.Open))
{
fs.Position = message.Position;
byte[] buffer = new byte[Math.Min(MAX_CHUNK_LENGTH, fs.Length - fs.Position)];
fs.Read(buffer, 0, buffer.Length);
Transporter.SendResponse(new FileChunkDownloadResponse()
{
Buffer = ByteString.CopyFrom(buffer),
}, request.Container.Token);
}
}
catch (Exception ex)
{
Transporter.SendResponse(new FileChunkDownloadResponse()
{
}, request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.FileRequestDenied, ErrorMessage = ex.Message });
}
}
private void HandleCreateRequest(TangoMessage request)
{
try
{
Directory.CreateDirectory(request.Message.Path);
Transporter.SendResponse(new CreateResponse(), request.Container.Token);
}
catch (Exception ex)
{
Transporter.SendResponse(new CreateResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.FileRequestInvalidParameter, ErrorMessage = ex.Message });
}
}
private void HandleDeleteRequest(TangoMessage request)
{
try
{
if (request.Message.Attribute == FileAttribute.Directory)
{
Directory.Delete(request.Message.Path, true);
}
else
{
File.Delete(request.Message.Path);
}
Transporter.SendResponse(new DeleteResponse(), request.Container.Token);
}
catch (Exception ex)
{
Transporter.SendResponse(new DeleteResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.FileRequestInvalidParameter, ErrorMessage = ex.Message });
}
}
private void HandleFileUploadRequest(TangoMessage request)
{
var message = request.Message;
_lastFileUploadRequest = message;
Transporter.SendResponse(new FileUploadResponse()
{
MaxChunkLength = MAX_CHUNK_LENGTH,
UploadID = Guid.NewGuid().ToString(),
}, request.Container.Token);
}
private void HandleFileChunkUploadRequest(TangoMessage request)
{
var message = request.Message;
try
{
using (FileStream fs = new FileStream(message.Path, FileMode.Append))
{
byte[] buffer = message.Buffer.ToByteArray();
fs.Write(buffer, 0, buffer.Length);
Debug.WriteLine($"Emulator file upload '{_lastFileUploadRequest.Path}' {fs.Length}/{_lastFileUploadRequest.Length} ...");
}
Transporter.SendResponse(new FileChunkUploadResponse(), request.Container.Token);
}
catch (Exception ex)
{
Transporter.SendResponse(new FileChunkUploadResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError, ErrorMessage = ex.Message });
}
}
private void HandleValidateVersionRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(3000);
try
{
using (FileStream fs = new FileStream(Path.Combine(request.Message.Path, MachineOperator.FIRMWARE_UPGRADE_CONFIG_FILE_NAME), FileMode.Open))
{
VersionPackageDescriptor package = VersionPackageDescriptor.Parser.ParseFrom(fs);
}
Transporter.SendResponse(new ValidateVersionResponse(), request.Container.Token);
}
catch (Exception ex)
{
Transporter.SendResponse(new ValidateVersionResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError, ErrorMessage = ex.Message });
}
});
}
private void HandleActivateVersionRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(3000);
try
{
using (FileStream fs = new FileStream(Path.Combine(request.Message.Path, MachineOperator.FIRMWARE_UPGRADE_CONFIG_FILE_NAME), FileMode.Open))
{
VersionPackageDescriptor package = VersionPackageDescriptor.Parser.ParseFrom(fs);
}
for (int i = 0; i < 100; i++)
{
Transporter.SendResponse(new ActivateVersionResponse()
{
Progress = i + 1,
Total = 100
}, request.Container.Token);
Thread.Sleep(10);
}
Transporter.SendResponse(new ActivateVersionResponse()
{
Progress = 100,
Total = 100
}, request.Container.Token, new TransportResponseConfig() { Completed = true });
}
catch (Exception ex)
{
Transporter.SendResponse(new ActivateVersionResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError, ErrorMessage = ex.Message });
}
});
}
private void HandleStartPowerDownRequest(TangoMessage request)
{
_abortPowerDown = false;
Task.Factory.StartNew(async () =>
{
MachineStatus.State = MachineState.ShuttingDown;
for (int i = 0; i < 100; i++)
{
if (_abortPowerDown) return;
await Task.Delay(200);
await Transporter.SendResponse(new StartPowerDownResponse()
{
ProgressPercentage = i++,
Message = $"Powering down {i}%..."
}, request.Container.Token);
}
await Task.Delay(500);
await Transporter.SendResponse(new StartPowerDownResponse()
{
ProgressPercentage = 100,
Message = "Machine is turned off",
State = PowerDownState.PowerOffCompleted
}, request.Container.Token, new TransportResponseConfig() { Completed = true });
});
}
private async void HandleAbortPowerDownRequest(TangoMessage request)
{
_abortPowerDown = true;
await Task.Delay(1000);
await Transporter.SendResponse(new AbortPowerDownResponse(), request.Container.Token);
}
private async void HandleStartThreadLoadingRequest(TangoMessage request)
{
_isThreadLoadingStarted = true;
_threadLoadingToken = request.Container.Token;
await Transporter.SendResponse(new StartThreadLoadingResponse(), request.Container.Token);
}
private async void HandleTryThreadLoadingRequest(TangoMessage request)
{
await Transporter.SendResponse(new TryThreadLoadingResponse(), request.Container.Token);
StartThreadLoading();
}
private async void HandleContinueThreadLoadingRequest(TangoMessage request)
{
if (_threadLoadingToken != null)
{
await Transporter.SendResponse(new ContinueThreadLoadingResponse(), request.Container.Token);
await Task.Delay(1000);
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.Finalizing }, _threadLoadingToken);
await Task.Delay(8000);
//if (_rnd.Next(0, 100) > 50)
//{
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.Completed }, _threadLoadingToken);
//}
//else
//{
// await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.FinalizationError, ErrorReason = "Emulator random error." }, _threadLoadingToken);
//}
}
else
{
await Transporter.SendResponse(new ContinueThreadLoadingResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError, ErrorMessage = "StartThreadLoadingRequest was never sent." });
}
}
private async void HandleStartHeadCleaningRequest(TangoMessage request)
{
_abortHeadCleaning = false;
for (int i = 0; i < 100; i++)
{
if (_abortHeadCleaning)
{
await Transporter.SendResponse(new StartHeadCleaningResponse()
{
}, request.Container.Token, new TransportResponseConfig()
{
Completed = true,
ErrorCode = ErrorCode.ContinuousResponseAborted
});
return;
}
await Task.Delay(200);
await Transporter.SendResponse(new StartHeadCleaningResponse()
{
Progress = i++,
Total = 100,
Status = $"Performing head cleaning..."
}, request.Container.Token);
}
await Task.Delay(500);
await Transporter.SendResponse(new StartHeadCleaningResponse()
{
Progress = 100,
Total = 100,
Status = "Completed",
}, request.Container.Token, new TransportResponseConfig() { Completed = true });
}
private async void HandleAbortHeadCleaningRequest(TangoMessage request)
{
if (_rnd.Next(0, 100) > 60)
{
_abortHeadCleaning = true;
await Task.Delay(1000);
await Transporter.SendResponse(new AbortHeadCleaningResponse(), request.Container.Token);
}
}
private async void HandleStartPowerUpRequest(TangoMessage request)
{
try
{
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Power up started...", ProgressPercentage = 10, State = PowerUpState.BuiltInTest }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Testing dispensers...", ProgressPercentage = 20, State = PowerUpState.DispenserPressureBuildupTest }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Heating started...", ProgressPercentage = 30, State = PowerUpState.HeatingStarted }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Heating started...", ProgressPercentage = 40, State = PowerUpState.HwConfig }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Hardware configuration...", ProgressPercentage = 50, State = PowerUpState.HwConfig }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Initializing blower...", ProgressPercentage = 60, State = PowerUpState.InitialBlowerActivation }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Thread detection...", ProgressPercentage = 70, State = PowerUpState.ThreadDetection }, request.Container.Token);
Thread.Sleep(1000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Waiting for cooler...", ProgressPercentage = 80, State = PowerUpState.WaitForCooler }, request.Container.Token);
Thread.Sleep(4000);
await Transporter.SendResponse(new StartPowerUpResponse() { Message = "Ready to dye...", ProgressPercentage = 90, State = PowerUpState.MachineReadyToDye }, request.Container.Token, new TransportResponseConfig()
{
Completed = true
});
}
catch (Exception ex)
{
LogManager.Log(ex);
}
}
private void HandleStartInkFillingStatusRequest(TangoMessage request)
{
Task.Factory.StartNew(() =>
{
while (IsStarted)
{
if (!_emulateCorruption)
{
Transporter.SendResponse(new StartInkFillingStatusResponse()
{
Status = InkFillingStatus
}, request.Container.Token);
}
Thread.Sleep(2000);
}
});
}
private async void HandleStandByRequest(TangoMessage request)
{
await Task.Delay(1500);
MachineStatus.State = MachineState.Sleep;
await Transporter.SendResponse(new StandByResponse(), request.Container.Token);
}
private async void HandleAttemptThreadJoggingRequest(TangoMessage request)
{
await Task.Delay(3000);
if (_rnd.Next(0, 100) > 50)
{
await Transporter.SendResponse(new AttemptThreadJoggingResponse(), request.Container.Token);
}
else
{
await Transporter.SendResponse(new AttemptThreadJoggingResponse(), request.Container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError });
}
}
private async void HandleDataStoreItemModifiedRequest(TangoMessage request)
{
await Transporter.SendResponse(new DataStoreItemModifiedResponse(), request.Container.Token);
GetDataStoreItem(new GetDataStoreItemRequest()
{
Collection = request.Message.Collection,
Key = request.Message.Key
});
}
private async void HandleJobPrepareRequest(TangoMessage request)
{
await Task.Delay(2000);
await Transporter.SendResponse(new JobPrepareResponse(), request.Container.Token);
}
private async void HandleSetInkAutoFillingModeRequest(TangoMessage request)
{
await Task.Delay(1000);
MachineStatus.AutoInkFillingEnabled = request.Message.Enable;
await Transporter.SendResponse(new SetInkAutoFillingModeResponse(), request.Container.Token);
}
private async void HandleBitResultsRequest(TangoMessage request)
{
await Task.Delay(10000);
BitResultsResponse response = new BitResultsResponse();
foreach (var bitType in Enum.GetValues(typeof(PMR.Diagnostics.BitType)).Cast().ToList())
{
BitResult result = new BitResult();
result.BitType = bitType;
var rnd = _rnd.Next(0, 100);
if (rnd < 25)
{
result.Status = BitResultStatus.Skipped;
result.Description = "Skipped";
}
else if (rnd >= 25 && rnd < 50)
{
result.Status = BitResultStatus.Passed;
}
else if (rnd >= 50 && rnd < 75)
{
result.Status = BitResultStatus.Failed;
result.Description = "Emulator error message";
}
else if (rnd >= 75)
{
result.Status = BitResultStatus.Warning;
result.Description = "Emulator warning message";
}
response.Results.Add(result);
}
await Transporter.SendResponse(response, request.Container.Token);
}
private async void HandleSpoolTypeChangedRequest(TangoMessage request)
{
LogManager.Log($"Spool type changed: '{request.Message.SpoolType}'.");
await Transporter.SendResponse(new SpoolTypeChangedResponse(), request.Container.Token);
}
private async void HandleInitiateInkFillingRequest(TangoMessage request)
{
await Task.Delay(1000);
await Transporter.SendResponse(new InitiateInkFillingResponse(), request.Container.Token);
}
private async void HandleGetVersionDescriptorsRequest(TangoMessage request)
{
GetVersionDescriptorsResponse response = new GetVersionDescriptorsResponse();
int v = 1;
foreach (var destination in Enum.GetValues(typeof(PMR.FirmwareUpgrade.VersionFileDestination)).Cast().ToList())
{
VersionFileDescriptor result = new VersionFileDescriptor();
result.Destination = destination;
result.Version = $"0.0.0.{v}";
v++;
response.Descriptors.Add(result);
}
await Transporter.SendResponse(response, request.Container.Token);
}
#endregion
#region Public Methods
public async Task ValidateCartridge()
{
var response = await Transporter.SendRequest(new CartridgeValidationRequest()
{
Action = CartridgeAction.Inserted,
}, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(10) });
return response.Message.Index;
}
public async void StartThreadLoading()
{
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.Preparing }, _threadLoadingToken);
await Task.Delay(8000);
//if (_rnd.Next(0, 100) > 50)
//{
// await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.PreparationError, ErrorReason = "Emulator preparation random error." }, _threadLoadingToken);
//}
//else
{
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.ReadyForLoading }, _threadLoadingToken);
}
}
public async void FinalizeThreadLoading()
{
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.Finalizing }, _threadLoadingToken);
await Task.Delay(3000);
if (_rnd.Next(0, 100) > 50)
{
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.Completed }, _threadLoadingToken);
}
else
{
await Transporter.SendResponse(new StartThreadLoadingResponse() { State = ThreadLoadingState.FinalizationError, ErrorReason = "Emulator finalization random error." }, _threadLoadingToken);
}
}
public void AbortJob()
{
_cancelJob = true;
}
public async void SetThreadLoadingState(ThreadLoadingState state)
{
await Transporter.SendResponse