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(new StartThreadLoadingResponse() { State = state, Message = $"{state.ToString()}", ErrorReason = "Fake emulator error" }, _threadLoadingToken); } public async void PerformDataStoreTest() { LogManager.Log("Starting data store test..."); { try { LogManager.Log("Testing Int32..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "int", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.Int32, Int32Value = 100 } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "int" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing float..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "float", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.Float, FloatValue = 101f } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "float" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing double..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "double", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.Double, DoubleValue = 102d } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "double" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing boolean..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "bool", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.Boolean, BooleanValue = true } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "bool" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing string..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "string", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.String, StringValue = "String Value" } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "string" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing bytes..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "bytes", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.Bytes, BytesValue = ByteString.CopyFromUtf8("Bytes TEST TEST TEST"), } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "bytes" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.Message.Item.BytesValue.ToStringUtf8()); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing proto..."); var response = await Transporter.SendRequest(new PutDataStoreItemRequest() { Collection = "TEST", Key = "proto", Item = new PMR.DataStore.DataStoreItem() { DataType = DataType.Proto, BytesValue = new CalculateRequest() { A = 10, B = 15 }.ToByteString(), ProtoType = DataStoreMessageType.CalculateRequest, } }); if (response.Container.Error != ErrorCode.None) { LogManager.Log("Put Failed."); LogManager.Log(response.ToJsonString()); } else { var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "proto" }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(CalculateRequest.Parser.ParseFrom(res.Message.Item.BytesValue).ToJsonString()); LogManager.Log(res.ToJsonString()); } } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing int default..."); var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "intDefault", DefaultItem = new PMR.DataStore.DataStoreItem() { DataType = DataType.Int32, Int32Value = 10, }, }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(res.ToJsonString()); } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } { try { LogManager.Log("Testing proto default..."); var res = await Transporter.SendRequest(new GetDataStoreItemRequest() { Collection = "TEST", Key = "protoDefault", DefaultItem = new PMR.DataStore.DataStoreItem() { DataType = DataType.Proto, BytesValue = (new CalculateRequest() { A = 10, B = 15 }).ToByteString(), ProtoType = DataStoreMessageType.CalculateRequest, }, }); LogManager.Log(res.Container.Error != ErrorCode.None ? "Get Failed." : "Passed."); LogManager.Log(CalculateRequest.Parser.ParseFrom(res.Message.Item.BytesValue).ToJsonString()); LogManager.Log(res.ToJsonString()); } catch (Exception ex) { LogManager.Log(ex, "Failed."); } } } public async void PutDataStoreItem(PutDataStoreItemRequest request) { LogManager.Log($"Sending PutDataStoreItemRequest:\n{request.ToJsonString()}"); try { var response = await Transporter.SendRequest(request); } catch (Exception ex) { LogManager.Log(ex, "Error putting data store item."); } } public async void GetDataStoreItem(GetDataStoreItemRequest request) { LogManager.Log($"Sending GetDataStoreItemRequest:\n{request.ToJsonString()}"); try { var response = await Transporter.SendRequest(request); String protoJson = String.Empty; try { if (response.Message.Item.DataType == DataType.Proto) { var type = MessageFactory.GetDataStorePMRTypeFromDataStoreMessageType(response.Message.Item.ProtoType); var instance = MessageFactory.ParseProtoMessage(response.Message.Item.BytesValue.ToByteArray(), type); protoJson = instance.ToJsonString(); } } catch (Exception ex) { protoJson = ex.Message; } LogManager.Log($"Received GetDataStoreItemResponse:\n{response.Message.ToJsonString()}\nProtobuf Message:\n{protoJson}"); } catch (Exception ex) { LogManager.Log(ex, "Error getting data store item."); } } public async void RequestWasteEmptying() { try { ThreadFactory.StartNew(() => { Thread.Sleep(2000); EventsStates.First(x => x.EventType == PMR.Diagnostics.EventType.CartridgesCoverOpen).IsActive = true; Thread.Sleep(2000); EventsStates.First(x => x.EventType == PMR.Diagnostics.EventType.CartridgesCoverOpen).IsActive = false; }); var response = await Transporter.SendRequest(new WasteReplaceRequest(), new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); LogManager.Log($"Waste Replace Approved: {response.Message.Approved}"); } catch (Exception ex) { LogManager.Log(ex); } } public void FailJobWithEvent() { _failJob = true; } #endregion } }