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
}
}