using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.PMR; using Tango.PMR.Diagnostics; using Tango.Transport; using Tango.Transport.Transporters; using System.Reactive.Linq; using System.Reactive.Concurrency; using System.Reactive.Threading; using Tango.PMR.Common; using Tango.PMR.Printing; using Tango.Integration.Observables; using System.Reactive.Subjects; using Tango.Integration.Printing; namespace Tango.Integration.Operators { /// /// Represents the Tango machine operator default implementation. /// /// /// public class MachineOperator : BasicTransporter, IMachineOperator { #region Events /// /// Occurs when there is new diagnostics data available. /// public event EventHandler DiagnosticsDataAvailable; #endregion #region Properties private bool _enableDiagnostics; /// /// Gets or sets a value indicating whether direct the embedded device to send diagnostics messages. /// public bool EnableDiagnostics { get { return _enableDiagnostics; } set { if (_enableDiagnostics != value) { _enableDiagnostics = value; RaisePropertyChangedAuto(); OnEnableDiagnosticsChanged(value); } } } #endregion #region Virtual Methods /// /// Called when the enable sensors update property has been changed /// /// if set to true [value]. protected virtual void OnEnableDiagnosticsChanged(bool value) { if (value && State == TransportComponentState.Connected) { SendContinuousRequest(new TangoMessage(new PushDiagnosticsRequest() { PushMotors = true, PushSensors = true, }, MessageType.PushDiagnosticsRequest)).ObserveOn(new NewThreadScheduler()).Subscribe( (response) => { OnDiagnosticsDataAvailable(response); }, (ex) => { //Do I need separate event for each one ?? }, () => { //What to do now ?? }); } } /// /// Invokes the event. /// /// The sensors data. protected virtual void OnDiagnosticsDataAvailable(PushDiagnosticsResponse data) { DiagnosticsDataAvailable?.Invoke(this, data); } #endregion #region Protected Methods /// /// Called when the component state has changed. /// /// The state. protected override void OnStateChanged(TransportComponentState state) { base.OnStateChanged(state); OnEnableDiagnosticsChanged(EnableDiagnostics); } #endregion #region Public Methods /// /// Prints the specified job using the specified job parameters. /// /// The job. /// Process parameters table /// public JobHandler Print(Job job, ProcessParametersTable processParameters) { JobRequest request = new JobRequest(); JobTicket ticket = new JobTicket(); ticket.EnableInterSegment = job.EnableInterSegment; ticket.InterSegmentLength = job.InterSegmentLength; ticket.Length = job.Length; ticket.WindingMethod = (JobWindingMethod)job.WindingMethod.Code; ProcessParameters process = new ProcessParameters(); process.DyeingSpeed = processParameters.DyeingSpeed; process.MinInkUptake = processParameters.MinInkUptake; process.MixerTemp = processParameters.MixerTemp; process.HeadZone1Temp = processParameters.HeadZone1Temp; process.HeadZone2Temp = processParameters.HeadZone2Temp; process.HeadZone3Temp = processParameters.HeadZone3Temp; process.HeadAirFlow = processParameters.HeadAirFlow; process.FeederTension = processParameters.FeederTension; process.PullerTension = processParameters.PullerTension; process.DryerBufferLength = processParameters.DryerBufferLength; process.DryerZone1Temp = processParameters.DryerZone1Temp; process.DryerZone2Temp = processParameters.DryerZone2Temp; process.DryerZone3Temp = processParameters.DryerZone3Temp; process.DryerAirFlow = processParameters.DryerAirFlow; process.WinderTension = processParameters.WinderTension; ticket.ProcessParameters = process; request.JobTicket = ticket; JobHandler handler = null; handler = new JobHandler(async () => { try { var result = await SendRequest(new AbortJobRequest()); handler.RaiseCanceled(); } catch (Exception) { //TODO: What to do in case job failed to cancel ?? } }); SendContinuousRequest(request).Subscribe((response) => { handler.RaiseStatusReceived(response.Message.Status); }, (ex) => { if (!handler.IsCanceled) { handler.RaiseFailed(ex); } }, () => { handler.RaiseCompleted(); }); return handler; } /// /// Starts jogging the specified motor. /// /// The request. /// public Task> StartMotorJogging(MotorJoggingRequest request) { return SendRequest(request); } /// /// Stops jogging the specified motor. /// /// The request. /// public Task> StopMotorJogging(MotorAbortJoggingRequest request) { return SendRequest(request); } /// /// Starts homing the specified motor. /// /// The request. /// public IObservable> StartMotorHoming(MotorHomingRequest request) { return SendContinuousRequest(request); } /// /// Stops homing the specified motor. /// /// The request. /// public Task> StopMotorHoming(MotorAbortHomingRequest request) { return SendRequest(request); } /// /// Starts jogging the specified dispenser. /// /// The request. /// public Task> StartDispenserJogging(DispenserJoggingRequest request) { return SendRequest(request); } /// /// Stops jogging the specified dispenser. /// /// The request. /// public Task> StopDispenserJogging(DispenserAbortJoggingRequest request) { return SendRequest(request); } /// /// Starts homing the specified dispenser. /// /// The request. /// public IObservable> StartDispenserHoming(DispenserHomingRequest request) { return SendContinuousRequest(request); } /// /// Stops homing the specified dispenser. /// /// The request. /// public Task> StopDispenserHoming(DispenserAbortHomingRequest request) { return SendRequest(request); } /// /// Turn on/off the specified digital output pin. /// /// The request. /// public Task> SetDigitalOut(SetDigitalOutRequest request) { return SendRequest(request); } /// /// Starts jogging the thread motion system. /// /// The request. /// public Task> StartThreadJogging(ThreadJoggingRequest request) { return SendRequest(request); } /// /// Stops jogging the thread motion system. /// /// The request. /// public Task> StopThreadJogging(ThreadAbortJoggingRequest request) { return SendRequest(request); } #endregion } }