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;
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 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;
#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; }
#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)
{
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()
{
MachineStatus = new MachineStatus();
MachineStatus.State = MachineState.Ready;
for (int i = 0; i < 8; i++)
{
MachineStatus.IDSPacksLevels.Add(new IDSPackLevel()
{
Index = i,
DispenserLevel = 130000000,
MidTankLevel = 2500,
});
}
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,
});
}
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();
}
private void ResetGraphFactors()
{
_graphAmplitude = 75;
_graphFrequency = 1;
}
#endregion
#region Override Methods
///
/// Called on new request message.
///
/// The sender.
/// The container.
protected override void OnTransporterRequestReceived(object sender, MessageContainer 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;
}
}
#endregion
#region Request Handlers
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 * 10);
var res = MessageFactory.CreateTangoMessage(request.Container.Token);
res.Message.Progress = i;
if (i == request.Message.Amount - 1) res.Container.Completed = true;
Transporter.SendResponse(res);
}
});
}
private void HandleStartDiagnosticsRequest(TangoMessage request)
{
_diagnostics_enabled = true;
_diagnosticsRequest = request.Message;
int value = 0;
Random rnd = new Random();
var cancelToken = CreateCancelToken();
Task.Factory.StartNew(() =>
{
while (_diagnostics_enabled && Transporter.State == TransportComponentState.Connected && !cancelToken.Canceled)
{
StartDiagnosticsResponse res = new StartDiagnosticsResponse();
DiagnosticsMonitors monitors = new DiagnosticsMonitors();
res.Monitors = monitors;
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);
}
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);
res.DigitalInterfaceStates.AddRange(_digitalOutputPinsStates.Concat(_digitalInputPinsStates));
res.ComponentsStates.AddRange(_componentsStates);
res.HeatersStates.AddRange(_heater_states);
res.ValvesStates.AddRange(_valveStates);
if (!EmulateCorruption)
{
Transporter.SendResponse(res, request.Container.Token);
}
Thread.Sleep(300);
}
});
}
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();
Task.Factory.StartNew(() =>
{
while (_machine_updates_enabled && Transporter.State == TransportComponentState.Connected && !cancelToken.Canceled)
{
var res = new StartMachineStatusUpdateResponse();
res.Status = MachineStatus;
if (!EmulateCorruption)
{
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.Info;
if (!EmulateCorruption)
{
Transporter.SendResponse(res, request.Container.Token);
}
Thread.Sleep(10);
counter_message++;
if (counter_message > 10)
{
counter_message = 0;
counter++;
}
}
});
}
private void HandleJobRequest(TangoMessage request)
{
MachineStatus.State = MachineState.PreparingJob;
JobTicket job = request.Message.JobTicket;
_current_job_ticket = job;
_current_job_resume_token = null;
if (_current_job_ticket.UploadStrategy == JobUploadStrategy.JobDescriptionFile)
{
using (FileStream fs = new FileStream(_current_job_ticket.JobDescriptionFile, FileMode.Open))
{
var segments = JobDescriptionFile.ReadJobDescriptionFile(fs);
_current_job_ticket.Segments.AddRange(segments);
}
var logedTicket = _current_job_ticket.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;
double progress = 0;
_cancelJob = false;
bool message_sent = false;
double length = job.Segments.Sum(x => x.Length) * (Math.Max(job.NumberOfUnits, 1));
Task.Factory.StartNew(() =>
{
MachineStatus.State = MachineState.RunningJob;
while (progress < length + job.ProcessParameters.DryerBufferLength * ProcessParametersTable.DRYER_METERS_PER_CYCLE && !_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);
}
}
progress += Math.Min((centimeter_per_second / 1000d), (length + job.ProcessParameters.DryerBufferLength * ProcessParametersTable.DRYER_METERS_PER_CYCLE) - progress);
Thread.Sleep(100);
}
_current_job_ticket = null;
if (_cancelJob)
{
if (_current_job_resume_token == null)
{
Transporter.SendResponse(new JobResponse()
{
}, request.Container.Token, false, ErrorCode.ContinuousResponseAborted);
}
else
{
Transporter.SendResponse(new ResumeCurrentJobResponse()
{
}, _current_job_resume_token, false, ErrorCode.ContinuousResponseAborted);
}
}
else
{
if (_current_job_resume_token == null)
{
Transporter.SendResponse(new JobResponse()
{
Status = new PMR.Printing.JobStatus()
{
Progress = length + job.ProcessParameters.DryerBufferLength * ProcessParametersTable.DRYER_METERS_PER_CYCLE,
}
}, request.Container.Token, !_cancelJob);
}
else
{
Transporter.SendResponse(new ResumeCurrentJobResponse()
{
Status = new PMR.Printing.JobStatus()
{
Progress = length + job.ProcessParameters.DryerBufferLength * ProcessParametersTable.DRYER_METERS_PER_CYCLE,
}
}, _current_job_resume_token, !_cancelJob);
}
}
MachineStatus.State = MachineState.Ready;
});
}
private void HandleAbortJobRequest(TangoMessage request)
{
_cancelJob = true;
Transporter.SendResponse(new AbortJobResponse(), request.Container.Token);
}
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, true);
_motorHomingRequestCodes.Remove(homeRequest.MotorType);
ResetGraphFactors();
});
}
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, 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, null, 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(() =>
{
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"
},
}, request.Container.Token, null, request.Message.Password == "1234" ? ErrorCode.None : ErrorCode.UnauthorizedConnection);
}
}
private void HandleStopDebugLogRequest(TangoMessage request)
{
_debug_logs_enabled = false;
Transporter.SendResponse(new StopDebugLogResponse(), request.Container.Token);
}
private void HandleUploadHardwareConfigurationRequest(TangoMessage request)
{
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, true, 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 = "/"
}, 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, false, failed ? ErrorCode.GeneralError : ErrorCode.None, 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, null, 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, null, ErrorCode.FileRequestDenied, 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, null, ErrorCode.FileRequestInvalidParameter, 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, null, ErrorCode.FileRequestInvalidParameter, 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, null, ErrorCode.GeneralError, 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, null, ErrorCode.GeneralError, 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);
}
Transporter.SendResponse(new ActivateVersionResponse(), request.Container.Token);
}
catch (Exception ex)
{
Transporter.SendResponse(new ActivateVersionResponse(), request.Container.Token, null, ErrorCode.GeneralError, ex.Message);
}
});
}
#endregion
#region Public Methods
public async Task ValidateCartridge()
{
var response = await Transporter.SendRequest(new CartridgeValidationRequest()
{
Action = CartridgeAction.Inserted,
}, TimeSpan.FromSeconds(10));
return response.Message.Index;
}
#endregion
}
}