Chronos Plugins 5.11.0
This documentation covers the plugin interfaces definitions and an example implementation.
Loading...
Searching...
No Matches
MockPlugin.Device.MockDevice Class Reference

A chronos plugin implementation for a fake device. We pretend we are controlling a mixture of coffee machine and waiter robot. More...

Inheritance diagram for MockPlugin.Device.MockDevice:
Collaboration diagram for MockPlugin.Device.MockDevice:

Public Member Functions

 MockDevice (IGuiHelper guiHelper)
void Dispose ()
void BrewFrappuccino (BrewFrappuccino.CompositionData composition)
 Pretend we are doing some operation on a complex parameter set.
void SomeDummyMethod ()
 Just for testing if methods of this device can be called from some other point in our code.
void Connect ()
 Inform the user of our connect attempt / success. Instead of establishing a real connection, show some message box.
void Disconnect ()
 Pretend we are closing the connection. Actual operation substituted by a message box.
void ShowTheMessage (string messageText)
 Let our device set a status message and display some message box instead of doing real work.
void TriggerAbort (string reason, bool softStop)
 This will trigger the AbortSchedule-Event 5 seconds after it was called from a task.
void CheckForAbort ()
Task ApplyParametersAsync (bool waitUntilSetpointIsReached, CancellationToken canToken)
 Set the given parameters on the device.
void WaitIfPaused ()
void BeginInteraction ()
 Will be called if interaction is started, gives you a chance to unlock a terminal, for example.
void EndInteraction ()
 Will be called if you can lock the terminal again.
void RaiseError (string errorDescription, ErrorType errType, bool resolved)
 "Retry" here means that we don't retry some action, but that we raise the error again.

Static Public Attributes

const string DeviceTypeName = "ACME Coffee Maker"

Properties

string DisplayedTypeName [get]
 Visible to the user on the instruments page of the settings editor.
string DeviceTypeDescription [get]
 Device class specification referred to by some messages.
string Name [get, set]
 User-selected name for the device instance.
string Connection = "COM17" [get, set]
 Connection as set in the Chronos instrument settings.
bool IsConnected [get, set]
 Helper for our toolbox.
CoffeMakerParams Parameters = new CoffeMakerParams() [get, set]
 Your parameter set.
bool Aborted [get, set]
 If set, abort execution as soon as possible. You can throw an OperationCanceledException. Will be set to false after termination of the run.
bool Paused [get, set]
 If paused, wait until paused is reset before executing the next command.
IEnumerable< string > LogPaths [get]
 Provide full paths to each of your log files here.
Func< StopRunArgs, Task > StopRun [get, set]
 Callback function returning a task that completes once the schedule queue was stopped.
IScheduleEvents ScheduleEvents [set]
 Hook up immediately or save this for later use.

Events

Action< ConnectionStateConnectionStateChanged
Action< string > SetStatusMessage
Action< string > DebugOutput
PropertyChangedEventHandler PropertyChanged
Action< string > AbortSchedule
EventHandler< InteractiveErrorHandlingEventArgsHandleError
Events inherited from AxelSemrau.Chronos.Plugin.IDevice
Action< ConnectionStateConnectionStateChanged
 Raise this event when your connection state has changed.
Events inherited from AxelSemrau.Chronos.Plugin.IProvideStatusMessages
Action< string > SetStatusMessage
 Raise this event to set your current status while doing something on the device. Messages passed to this event will be shown in the "Autosampler status" line.
Events inherited from AxelSemrau.Chronos.Plugin.IHaveDebugOutput
Action< string > DebugOutput
 Messages passed to this event will be logged (including a timestamp) to the user configured debug logfile.
Events inherited from AxelSemrau.Chronos.Plugin.IAbortSchedules
Action< string > AbortSchedule
 If you raise this event, the schedule will be aborted.
Events inherited from AxelSemrau.Chronos.Plugin.IHaveInteractiveErrorHandling
EventHandler< InteractiveErrorHandlingEventArgsHandleError
 Raise this event if you want the user to decide how to continue, if this is desired in the settings.

Private Member Functions

void OnIsConnectedChanged ()
 For thread-safe update of the toolbox's GUI elements representing the connection state.
void ScheduleStateChangedHandler (object sender, ScheduleStateEventArgs e)

Private Attributes

bool mIsConnected
readonly ManualResetEventSlim mPauseEnded = new ManualResetEventSlim(true)
 Using an event here instead of a simple bool helps us avoid polling while checking for the events.
readonly ManualResetEventSlim mAborted = new ManualResetEventSlim(false)
IScheduleEvents mScheduleEvents
readonly IGuiHelper mGuiHelper

Detailed Description

A chronos plugin implementation for a fake device. We pretend we are controlling a mixture of coffee machine and waiter robot.

Just an example implementation that doesn't do any real work.

Definition at line 38 of file MockDevice.cs.

Constructor & Destructor Documentation

◆ MockDevice()

MockPlugin.Device.MockDevice.MockDevice ( IGuiHelper guiHelper)

Definition at line 63 of file MockDevice.cs.

64 {
65 mGuiHelper = guiHelper;
66 Instances.Add(this);
67 }

References mGuiHelper.

Member Function Documentation

◆ ApplyParametersAsync()

Task MockPlugin.Device.MockDevice.ApplyParametersAsync ( bool waitUntilSetpointIsReached,
CancellationToken cancelToken )

Set the given parameters on the device.

Parameters
waitUntilSetpointIsReachedParameter setting is done in two turns: The first call will ask you to set all controls to the new setpoints, the second call will ask you to wait until they are actually reached. Return as soon as possible from the first call, and to not return from the second call before you are definitely ready.
cancelTokenIf requested, abort waiting for the desired temperature.

Implements AxelSemrau.Chronos.Plugin.IHaveMachineParameters< ParamType >.

Definition at line 268 of file MockDevice.cs.

269 {
270
271 SetStatusMessage?.Invoke($"Applying parameters: '{Parameters}' and {(!waitUntilSetpointIsReached ? "not " : "")} waiting for setpoint.");
272 if (waitUntilSetpointIsReached)
273 {
274 return Task.Delay(TimeSpan.FromSeconds(10),canToken);
275 }
276 return Task.CompletedTask;
277 }

References SetStatusMessage.

◆ BeginInteraction()

void MockPlugin.Device.MockDevice.BeginInteraction ( )

Will be called if interaction is started, gives you a chance to unlock a terminal, for example.

Implements AxelSemrau.Chronos.Plugin.IHaveInteractiveErrorHandling.

Definition at line 356 of file MockDevice.cs.

357 {
358 DebugOutput?.Invoke("Starting error handling interaction");
359 }

References DebugOutput.

◆ BrewFrappuccino()

void MockPlugin.Device.MockDevice.BrewFrappuccino ( BrewFrappuccino.CompositionData composition)

Pretend we are doing some operation on a complex parameter set.

Parameters
composition

Definition at line 97 of file MockDevice.cs.

98 {
99 WaitIfPaused();
100 ShowTheMessage(
101 $"Making a {composition.Volume} mL frappuccino with cream type \"{composition.Cream}\"{(composition.DeCaffeinated ? ", decaffeinated." : "")}.");
102 }

References BrewFrappuccino(), ShowTheMessage(), and WaitIfPaused().

Referenced by BrewFrappuccino().

◆ CheckForAbort()

void MockPlugin.Device.MockDevice.CheckForAbort ( )

Definition at line 254 of file MockDevice.cs.

255 {
256 if (mAborted.IsSet)
257 {
258 throw new OperationCanceledException("Aborted");
259 }
260 }

References mAborted.

Referenced by WaitIfPaused().

◆ Connect()

void MockPlugin.Device.MockDevice.Connect ( )

Inform the user of our connect attempt / success. Instead of establishing a real connection, show some message box.

Implements AxelSemrau.Chronos.Plugin.IDevice.

Definition at line 115 of file MockDevice.cs.

116 {
117 ConnectionStateChanged(ConnectionState.Connecting);
118 MessageBox.Show(mGuiHelper.MainWindow, $"Device {Name} was connected to {Connection}.");
119 ConnectionStateChanged(ConnectionState.Connected);
120 mIsConnected = true;
121 OnIsConnectedChanged();
122 }
ConnectionState
If your connectivity state changes, you should tell the user about it.

References ConnectionStateChanged, mGuiHelper, mIsConnected, and OnIsConnectedChanged().

◆ Disconnect()

void MockPlugin.Device.MockDevice.Disconnect ( )

Pretend we are closing the connection. Actual operation substituted by a message box.

Implements AxelSemrau.Chronos.Plugin.IDevice.

Definition at line 127 of file MockDevice.cs.

128 {
129 ConnectionStateChanged(ConnectionState.Disconnecting);
130 MessageBox.Show(mGuiHelper.MainWindow, $"Device {Name} was disconnected from {Connection}.");
131 ConnectionStateChanged(ConnectionState.Disconnected);
132 mIsConnected = false;
133 OnIsConnectedChanged();
134 }

References ConnectionStateChanged, mGuiHelper, mIsConnected, and OnIsConnectedChanged().

◆ Dispose()

void MockPlugin.Device.MockDevice.Dispose ( )

Definition at line 71 of file MockDevice.cs.

72 {
73 Instances.Remove(this);
74 DebugOutput?.Invoke($"MockDevice {Name} disposed");
75 }

References DebugOutput.

◆ EndInteraction()

void MockPlugin.Device.MockDevice.EndInteraction ( )

Will be called if you can lock the terminal again.

Implements AxelSemrau.Chronos.Plugin.IHaveInteractiveErrorHandling.

Definition at line 361 of file MockDevice.cs.

362 {
363 DebugOutput?.Invoke("Ending error handling interaction");
364 }

References DebugOutput.

◆ OnIsConnectedChanged()

void MockPlugin.Device.MockDevice.OnIsConnectedChanged ( )
private

For thread-safe update of the toolbox's GUI elements representing the connection state.

Definition at line 208 of file MockDevice.cs.

209 {
210 var myHandler = PropertyChanged;
211 if (myHandler != null)
212 {
213 mGuiHelper.GuiTaskFactory.StartNew(() => myHandler(this, new PropertyChangedEventArgs(nameof(IsConnected))));
214 }
215 }

References IsConnected, mGuiHelper, and PropertyChanged.

Referenced by Connect(), and Disconnect().

◆ RaiseError()

void MockPlugin.Device.MockDevice.RaiseError ( string errorDescription,
ErrorType errType,
bool resolved )

"Retry" here means that we don't retry some action, but that we raise the error again.

Parameters
errorDescription
errType
resolved

Definition at line 372 of file MockDevice.cs.

373 {
374 var errArgs = new InteractiveErrorHandlingEventArgs() { Error = errorDescription, ErrorType = errType };
375 do
376 {
377 HandleError?.Invoke(this, errArgs);
378 } while (errArgs.RetryLastAction);
379
380 if (!resolved)
381 {
382 throw new IOException($"Coffee machine reported a problem: {errorDescription}");
383 }
384 }
ErrorType
Lets a device implementing IHaveInteractiveErrorHandling specify which kind of error occurred.

References HandleError.

◆ ScheduleStateChangedHandler()

void MockPlugin.Device.MockDevice.ScheduleStateChangedHandler ( object sender,
ScheduleStateEventArgs e )
private

Definition at line 350 of file MockDevice.cs.

351 {
352 DebugOutput?.Invoke($"Schedule {e.PlanerName} ({e.PlanerID}) state {e.State}, abort reason {(string.IsNullOrEmpty(e.AbortReason) ? "N/A" : e.AbortReason)}");
353 }

References DebugOutput.

◆ ShowTheMessage()

void MockPlugin.Device.MockDevice.ShowTheMessage ( string messageText)

Let our device set a status message and display some message box instead of doing real work.

Parameters
messageText

Definition at line 159 of file MockDevice.cs.

160 {
161 WaitIfPaused();
162 SetStatusMessage?.Invoke("The device just did something wonderful.");
163 MessageBox.Show(mGuiHelper.MainWindow,
164 $"The following message was shown addressing the mock device {Name}:\r\n{messageText}",
165 "Mock Device",
166 MessageBoxButtons.OK);
167 DebugOutput?.Invoke($"Finished showing the message {messageText}");
168 }

References DebugOutput, mGuiHelper, SetStatusMessage, and WaitIfPaused().

Referenced by BrewFrappuccino().

◆ SomeDummyMethod()

void MockPlugin.Device.MockDevice.SomeDummyMethod ( )

Just for testing if methods of this device can be called from some other point in our code.

Definition at line 107 of file MockDevice.cs.

108 {
109 DebugOutput?.Invoke($"Dummy method of {Name} was called.");
110 }

References DebugOutput.

◆ TriggerAbort()

void MockPlugin.Device.MockDevice.TriggerAbort ( string reason,
bool softStop )

This will trigger the AbortSchedule-Event 5 seconds after it was called from a task.

Parameters
reason
softStop

For a real device, this would be something like a leak, a failed pump or heater or anything else that makes it impossible to operate the device properly.

Definition at line 232 of file MockDevice.cs.

233 {
234 Task.Run(() =>
235 {
236 Thread.Sleep(5000);
237 if (softStop)
238 {
239 StopRun?.Invoke(new StopRunArgs()
240 {
241 How = StopRunArgs.StopMode.NoNewJobs, StopQueue = true, Reason = reason,
242 RestartRemainingJobs = false
243 });
244 }
245 else
246 {
247 AbortSchedule?.Invoke(reason);
248 }
249 });
250}

References AbortSchedule, and StopRun.

◆ WaitIfPaused()

void MockPlugin.Device.MockDevice.WaitIfPaused ( )

Definition at line 281 of file MockDevice.cs.

282 {
283 WaitHandle.WaitAny(new[] { mPauseEnded.WaitHandle, mAborted.WaitHandle });
284 CheckForAbort();
285 }

References CheckForAbort(), and mPauseEnded.

Referenced by BrewFrappuccino(), and ShowTheMessage().

Member Data Documentation

◆ DeviceTypeName

const string MockPlugin.Device.MockDevice.DeviceTypeName = "ACME Coffee Maker"
static

Definition at line 54 of file MockDevice.cs.

◆ mAborted

readonly ManualResetEventSlim MockPlugin.Device.MockDevice.mAborted = new ManualResetEventSlim(false)
private

Definition at line 294 of file MockDevice.cs.

Referenced by CheckForAbort().

◆ mGuiHelper

readonly IGuiHelper MockPlugin.Device.MockDevice.mGuiHelper
private

Definition at line 331 of file MockDevice.cs.

Referenced by Connect(), Disconnect(), MockDevice(), OnIsConnectedChanged(), and ShowTheMessage().

◆ mIsConnected

bool MockPlugin.Device.MockDevice.mIsConnected
private

Definition at line 57 of file MockDevice.cs.

Referenced by Connect(), and Disconnect().

◆ mPauseEnded

readonly ManualResetEventSlim MockPlugin.Device.MockDevice.mPauseEnded = new ManualResetEventSlim(true)
private

Using an event here instead of a simple bool helps us avoid polling while checking for the events.

Definition at line 292 of file MockDevice.cs.

Referenced by WaitIfPaused().

◆ mScheduleEvents

IScheduleEvents MockPlugin.Device.MockDevice.mScheduleEvents
private

Definition at line 330 of file MockDevice.cs.

Property Documentation

◆ Aborted

bool MockPlugin.Device.MockDevice.Aborted
getset

If set, abort execution as soon as possible. You can throw an OperationCanceledException. Will be set to false after termination of the run.

Implements AxelSemrau.Chronos.Plugin.ICanInterrupt.

Definition at line 296 of file MockDevice.cs.

297 {
298 get => mAborted.IsSet;
299 set
300 {
301 if (value) { mAborted.Set(); } else { mAborted.Reset(); }
302 }
303 }

◆ Connection

string MockPlugin.Device.MockDevice.Connection = "COM17"
getset

Connection as set in the Chronos instrument settings.

If this gets a bit more complicated, you can also use a UITypeEditor here.

Implements AxelSemrau.Chronos.Plugin.INeedAConnection.

Definition at line 149 of file MockDevice.cs.

149{ get; set; } = "COM17";

◆ DeviceTypeDescription

string MockPlugin.Device.MockDevice.DeviceTypeDescription
get

Device class specification referred to by some messages.

Implements AxelSemrau.Chronos.Plugin.IDevice.

Definition at line 85 of file MockDevice.cs.

◆ DisplayedTypeName

string MockPlugin.Device.MockDevice.DisplayedTypeName
get

Visible to the user on the instruments page of the settings editor.

Implements AxelSemrau.Chronos.Plugin.IDevice.

Definition at line 80 of file MockDevice.cs.

◆ IsConnected

bool MockPlugin.Device.MockDevice.IsConnected
getset

Helper for our toolbox.

Definition at line 173 of file MockDevice.cs.

174 {
175 get => mIsConnected;
176 set
177 {
178 if (!mIsConnected && value)
179 {
180 Connect();
181 }
182 else if (mIsConnected && !value)
183 {
184 Disconnect();
185 }
186 }
187 }

Referenced by OnIsConnectedChanged().

◆ LogPaths

IEnumerable<string> MockPlugin.Device.MockDevice.LogPaths
get

Provide full paths to each of your log files here.

Implements AxelSemrau.Chronos.Plugin.IProvideDiagnosticLogs.

Definition at line 323 of file MockDevice.cs.

◆ Name

string MockPlugin.Device.MockDevice.Name
getset

User-selected name for the device instance.

Please return what you are given. Note: Before Chronos 5.1.8, this was set to "Uninitialized Device" for temporary device instances. With later versions, the name should only be set for a "real" instance.

Implements AxelSemrau.Chronos.Plugin.IDevice.

Definition at line 87 of file MockDevice.cs.

88 {
89 get;
90 set;
91 }

◆ Parameters

CoffeMakerParams MockPlugin.Device.MockDevice.Parameters = new CoffeMakerParams()
getset

Your parameter set.

Before sequence start, this will be set to the desired values. Wait until ApplyParameters is called to actually transmit these values to the device.

Implements AxelSemrau.Chronos.Plugin.IHaveMachineParameters< ParamType >.

Definition at line 266 of file MockDevice.cs.

266{ get; set; } = new CoffeMakerParams();

◆ Paused

bool MockPlugin.Device.MockDevice.Paused
getset

If paused, wait until paused is reset before executing the next command.

Implements AxelSemrau.Chronos.Plugin.ICanInterrupt.

Definition at line 305 of file MockDevice.cs.

306 {
307 get => !mPauseEnded.IsSet;
308 set
309 {
310 if (value)
311 {
312 mPauseEnded.Reset();
313 }
314 else
315 {
316 mPauseEnded.Set();
317 }
318 }
319 }

◆ ScheduleEvents

IScheduleEvents MockPlugin.Device.MockDevice.ScheduleEvents
set

Hook up immediately or save this for later use.

Implements AxelSemrau.Chronos.Plugin.IScheduleStateAware.

Definition at line 333 of file MockDevice.cs.

334 {
335 set
336 {
337 if (mScheduleEvents != null)
338 {
339 mScheduleEvents.ScheduleStateChanged -= ScheduleStateChangedHandler;
340 }
341
342 mScheduleEvents = value;
343 if (value != null)
344 {
345 mScheduleEvents.ScheduleStateChanged += ScheduleStateChangedHandler;
346 }
347 }
348 }

◆ StopRun

Func<StopRunArgs, Task> MockPlugin.Device.MockDevice.StopRun
getset

Callback function returning a task that completes once the schedule queue was stopped.

Implements AxelSemrau.Chronos.Plugin.IStopRuns.

Definition at line 326 of file MockDevice.cs.

326{ get; set; }

Referenced by TriggerAbort().

Event Documentation

◆ AbortSchedule

Action<string> MockPlugin.Device.MockDevice.AbortSchedule

Definition at line 252 of file MockDevice.cs.

Referenced by TriggerAbort().

◆ ConnectionStateChanged

Action<ConnectionState> MockPlugin.Device.MockDevice.ConnectionStateChanged

Definition at line 136 of file MockDevice.cs.

Referenced by Connect(), and Disconnect().

◆ DebugOutput

Action<string> MockPlugin.Device.MockDevice.DebugOutput

◆ HandleError

EventHandler<InteractiveErrorHandlingEventArgs> MockPlugin.Device.MockDevice.HandleError

Definition at line 385 of file MockDevice.cs.

Referenced by RaiseError().

◆ PropertyChanged

PropertyChangedEventHandler MockPlugin.Device.MockDevice.PropertyChanged

Definition at line 217 of file MockDevice.cs.

Referenced by OnIsConnectedChanged().

◆ SetStatusMessage

Action<string> MockPlugin.Device.MockDevice.SetStatusMessage

Definition at line 193 of file MockDevice.cs.

Referenced by ApplyParametersAsync(), and ShowTheMessage().


The documentation for this class was generated from the following file: