-
Notifications
You must be signed in to change notification settings - Fork 0
/
working notes.txt
938 lines (513 loc) · 36.3 KB
/
working notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
Overlord Simulator: add argument parsing for -r, -c, -m, -v
Overlord Simulator: add scrollbars to ovp xml textbox
Overlord Simulator: add ListView to display Overlord input variables
Overlord Simulator: add test Dictionary object to display to variables ListView
Overlord Simulator: add code to display variables set from command line to ListView
Overlord Simulator: Add animation to progress bar for simTime
Overlord Simulator: Add Pause/Resume button for simulation time; Implement -c option (close when done)
Overlord Simulator: Add Stop Now button for simulation time;
Overlord Simulator: Implement -r (run immediately), and -m (run minimized) options
Overlord Simulator: Implement code to handle when no command line arguments are passed
Overlord Simulator: Disable Pause button when sim progress finishes (if -c option not given)
Overlord Simulator: Add LMSF icon
LMSF Scheduler: Setup App layout, menu bar, and tool bar
LMSF Scheduler: Add ListView and Panel to display experiment steps, and buttons (Add, Duplicate, Delete, Move Up, Move Down) to organize steps
LMSF Scheduler: Add AutomationStep class to hold info about each automation step
LMSF Scheduler: Add ListOfSteps ObservableCollection and have it displayed in the ListBox with a DataTemplate
LMSF Scheduler: Add StepIcon as property for AutomationStep class and display icon in ListBox w/ DataTemplate
LMSF Scheduler: Add event handling for addStep Button with place-holder ListOfSteps.Add()
LMSF Scheduler: Add ContentControl on right hand side of main Window to display details of selected text, and implement place-holder code for data Binding
LMSF Scheduler: Add INotifyPropertyChanged interface to Main Window class, also add test buttons and text boxes to test data binding
LMSF Scheduler: Change Add Step code to add step after selected step )instead of at end of Collection
LMSF Scheduler: Implement code for Duplicate Step button
LMSF Scheduler: Add wait and dialog icons to AutomationStep class
LMSF Scheduler: Implement code for Delete Step, Move Up, and Move Down buttons
LMSF Scheduler: Add Dialog box for Add New Step
LMSF Scheduler: Add Rodio buttons to select step type for Add New Step
LMSF Scheduler: Take out temporary ListOfSteps initialization code, and edit Add, Duplicate, Delete, ect methods to deal appropriately with empty list
LMSF Scheduler: Add LMSF icon bitmap as default image for steps
LMSF Scheduler: Switch to purely text-based step editing and specification; make new branch, graphicStepEditor, for old GUI
In new method, replace ListBox with TextBox, and remove buttons for manipulating steps (Add, Duplicate, etc.)
LMSF Scheduler: Add code for Open/Save/SaveAs, and deal with Focus issue for menu items (IsFocusScope="False")
LMSF Scheduler: Add button and code for "Insert File Path" - to insert the selected file path into the InputText
LMSF Scheduler: Make input and output Text Boxes accept enter, nowrap, auto scroll bars; fix Binding/Focus issue for Toolbar items (IsFocusScope="False")
LMSF Scheduler: Finish File menu functions, and add code to prompt for file save when inputText has changed as appropriately
LMSF Scheduler: Fix code for "Insert File Path" so that file path string is inserted at the textBox caret location;
insert ParseSteps() method to break up inputText into lines; Add Rewind button; Add blank button click handlers for Play, Step, Pause, etc.
LMSF Scheduler: Add inputTextBox.Focus() at the end of each menu item action to return focus to the text box
LMSF Scheduler: Add filename to main window title, with * to indicate unsaved changes
LMSF Scheduler: Rename "startButton" -> "playButton"; add fields for parsing and running steps; and add test code for line/step parsing
LMSF Scheduler: Add validate button to test string parsing; fix tooltip text for other buttons
LMSF Scheduler: Add Overlord to step parser; Add basic validation method run when validateButton clicked (same as Play, but sets isValidating flag so actual actions can be turned off)
LMSF Scheduler: Add System.Diagnostics.Process code to run Overlord.Main.exe
Overlord Simulator: Set Main window icon = LMSF icon
LMSF Scheduler: Switch path to Ovderlord.Main.exe to actual location (C:\Program Files (x86)\PAA\Overlord3)
Overlord Simulator: Capitalize method names to conform with reccomended C# style
LMSF Scheduler: Add code to wait between steps (clunky right now since it runs on the main thread, TODO: set it up to run steps on a separate thread)
LMSF Scheduler: Wrap waitingForStepCompletion in a propety with getter and setter
LMSF Scheduler: Run Steps on separate (BackgroundWorker) thread so that GUI updates are maintained
LMSF Scheduler: Modifiy ValidateButton_Click() to work with new multi-thread methods (validation runs like play but on main thread)
LMSF Scheduler: Add code to check for existence of ovp files during validation/running
LMSF Scheduler: Add Validation before every run
LMSF Scheduler: Change output text box to have line wrapping
LMSF Scheduler: Add Wait step to step parser; also add RunWaitStep() method, TODO: re-write RunWaitStep() with pop-up progress bar + cancel button
LMSF Scheduler: Rearange RunWaitStep() method; move WaitingForStepCompletion = false to OutsideProcessMonitor_RunWorkerCompleted; Rename ovWorker -> ovMonitorWorker
LMSF Scheduler: Move Background worker that waits for Overlord into a different step.
So now, Overlord steps start Overord and go on to the next step;
The new "WaitFor" step is then used to specifically wait for the Overlord step to finish;
Also included code to prevent two Overlord processes from running at the same time
Add new LMSF_Utilities library to solution
LMSF_Utilities: Add TimerDialog
LMSF Scheduler: Add test code for TimerDialog (on TestButton_Click)
LMSF_Utilities.TimerDialog: Add IsClosed Property to allow Scheduler to check if the TimerDialog has closed.
LMSF Scheduler: In StepParser(), replace Wait step with Timer step; Also replace RunWaitStep() with RunTimer()
Switch from "BackgroundWorker runStepsWorker" to "Thread runStepsThread" to create the thread that handles running steps,
Why? Since I thought "thread.SetApartmentState(ApartmentState.STA)" would be necessary to access GUI components (like the TimerDialog)
from the step-runner thread. It turns out that is not true (program seems to run just fin with the SetApartmentState commented out).
What is actually needed is to use a Dispatcher for lines of code in the step-runner methods that interact with the GUI,
e.g., this.Dispatcher.Invoke(() => { IsRunning = false; });
"IsRunning" calls "UpdateEnabledState" which sets the enabled state of GUI components appropriatly
Anyway, I'm not sure if the Dispatcher thing would have worked in a background thread, and I don't want to take the time to find out, since the code now works.
Notes added later: the Dispatcher things works from a background worker; I used it to display the time remaining in the TimerDialog class.
LMSF Scheduler: Make play, pause, etc. buttons not focusable, and then insert "inputTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();"
at the beginning of each button clicked method to makse sure the inputText gets updated appropriately.
LMSF Scheduler: Finish single-step button method, and implement abort button method
LMSF Scheduler: On main page, add visual indicator of run/paused state and abort called - with red/yellow/green colors
LMSF Scheduler: Add WaitForTimer() method and code to ParseSteps()
LMSF_Utilities: Add SharedParameters Class for storage of constants used by Utility methods
LMSF_Utilities: Add MetaItem class; and SharedParameters.GetMetaList() method to parse meta-item lists
LMSF_Utilities: Add SharedParameters.SortMetaList() method
LMSF_Utilities: Add SharedParameters.SortAndSaveMetaList() method; fix encoding issue that caused problems with Hamilton Venus (use default encoding instead of UTF8)
LMSF_Utilities: Add new class: SelectMetaIdentDialog, with placeholder code for CreateNewIdentier() methods
LMSF_Utilities: Finish GetMetaIdentifier(), and most of CreateNewIdentier() (still has some TODO commetns in it)
LMSF_Utilities: Add RegexValidationRule() and bindings to enforce validity of short identifiers in NewMetaIdentDialog
LMSF_Utilities: Add NewLongNameDialog, NotesDialog
LMSF_Utilities: Add NotesDialog and finish code for CreateNewIdentier()
LMSF_Utilities: Set up Combo boxes to initially have slectedIndex = -1 (no item selected)
LMSF_Utilities.GetMetaIdentifier: On cancel, make sure GetMetaIdentifier returns empty string.
LMSF_Utilities: Finish CreateNewMediaIdentifier() and MediaIngredientsDialog class
LMSF_Utilities: Add ConcentrationDialog class
LMSF Scheduler: Reorganize ParseSteps() method with Local functions to parse each step type
LMSF Scheduler: Fix Bug: Output does not show/update text for variables passed to Overlord
LMSF Scheduler: Add/midify code to properly deal with Main Window closing - either through the red 'X' or the File.Close()
LMSF Scheduler: Fix Bug: inputTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); - causes InputChanged <- true, even when it has not changed;
slight change in Setter to fix
LMSF Scheduler: Fix Bug: Will not Validate after Aborted run;
LMSF Scheduler: display validation result prominently with gree/red colr to indicate success/fail
LMSF Scheduler: Put DateTime info in Output text;
LMSF Scheduler: Add Running/Validating and ExperimentFileName to beginning of OutputText
LMSF Scheduler: Add saving of output text to log file
LMSF Scheduler: Add ComboBox on toolbar for shortcuts to insert Command into InputText
LMSF Scheduler: Move InsertFileButton to tool bar
LMSF Scheduler: Change WaitForOverlord() output to "... waiting for Overlord to finish and exit."
LMSF Scheduler: Add code to create log file directory if it does not exist, also changed the log file directory to: "C:\\Shared Files\\LMSF Scheduler\\LogFiles\\"
LMSF Scheduler: Change format for log file name to , "yyyy-MM-dd HH.mm.ss"
LMSF Scheduler: Turn play and step buttons yellow when waiting to resume from pause; also use predefined Brushes everywhere else: Brushes.NamedBrush
LMSF Scheduler: Add "Method Aborted." to log file
LMSF Scheduler: "project" to metadata type (same dialogs as additive/antibiotic)
LMSF Scheduler: Add local method, ParseGenericStep(), in ParseSteps(), as a template for new local parse methods
LMSF Scheduler: NewXML and SaveXML steps to ParseSteps(); and RunNewXml() and RunSaveXml() methods
LMSF Scheduler: Add AddXmlStep() method, and argument handling in ParseNewXml() to assign value to experimentStep attribute in XML aoutput
LMSF_Utilities: Add GetDateTimeString() method for consistent formatting of DateTime string: "yyyy-MM-dd HH:mm:ss", for everything except log file names
LMSF Scheduler: Add AddXmlStep() method, and argument handling in ParseNewXml() to assign value to experimentStep attribute in XML aoutput
LMSF Scheduler: Change code for RunNewXml() so that if 'Cancel' is selected at the "select project" dialog, the run will abort
LMSF Scheduler: Allow commenting input lines with "//"
LMSF Scheduler: Change XML schema a bit: metadata/project/protocol/<step> instead of metadata/project/experimentStep/<step>
LMSF Scheduler: Fix "procedure started" and "procedure finished" bugs
LMSF Scheduler: AddDateTimeNodes(XmlNode parentNode)
LMSF Scheduler: Add datetime info to protocol start/finish in XML;
LMSF Scheduler: Change signature of RunTimer() method to RunTimer(int num, string[] args) to be consistent with other RunXxxx() methods
LMSF Scheduler: Add command: WaitFor, DateTime
LMSF Scheduler: Add command: AppendXML
LMSF Scheduler: Add command: UserPrompt; make shortcut drop-down box a bit wider
LMSF Scheduler: Change command-argument separator to foreward slash "/" - to allow use of commas and semicolons in arguments.
LMSF Scheduler: Add key syntax to arguments: any {keyString}, inclosed with "{" and "}", in an inputText argument will be replaced with the corresponding value from the metaDictionary
LMSF Scheduler: Add Set command to directly set entries in metaDictionary
LMSF Scheduler: Add Get command, calls up a user dialog to get a metadata type and saves the result in the metaDictionary
LMSF_Utilities: Fix Bug; "none" not showing up in parent list for create new identifier
LMSF Scheduler: Add "Validate with User Input" check box - when checked, the validate method goes through all the user dialogs
LMSF Scheduler: Add XML metadata output at end of RunGet() method
LMSF Scheduler: Add concDictionary (Dictionary<string, Concentration>) to store user input concentrations
LMSF Scheduler: Add Get/ concentration/... command, with automated XML output
LMSF Scheduler: Change default prompt on Get/ command to use the "key" instead of "type"
LMSF Scheduler: Add code to NewXML/ command: automatically add the protocol type to the metadata dictionary, metaDictionary["protocol type"] = protocolType;
LMSF Scheduler: Add "default" as prompt parameter in Get/ command; update help file
LMSF Scheduler: Fix bug: When 'Cancel' selected in Get/ concentration/..., the run needs to abort before trying to reference the concentration object, which is null.
LMSF_Utilities: User prompt dialog open in center of screen
LMSF Scheduler: Fix Bug: "/" getting insterted when short-cut comboBox returns null
LMSF_Utilities: Add GetExperimentId Dialog and method
LMSF Scheduler: Implement GetExpID/ command and RunGetExpId()
Also, modify signature of AddDateTimeNodes(DateTime dt, XmlNode parentNode, string statusStr) to take DateTime object as first argument (so it can add dateTime info other than DateTime.Now)
LMSF Scheduler: Fix Bug in "Get/ concentration" command- concentration node was being appended to the additives instead of the last additive node
LMSF Scheduler: In GetExpID/ command, delete automatically created directory if it is not used (user choosed to same xml file somewhere else)
LMSF Scheduler: Add command: Get/ notes/ <key>/ <prompt>, to get notes from the user and append them as a notes node to the protocol node in the XML document
LMSF Scheduler: Add commands: Hamilton/ <method file>, and WaitFor/ Hamilton, to run Hamilton Venus methods (similar to Overlord/ command)
LMSF Scheduler: Add startDate to metaDictionary (same string as startDateTime, but without the time)
LMSF Scheduler: Add Get/ number/ - to get generic numberic input from user, with prompt
LMSF Scheduler: Add "Start/ <protocol title>/ <list file path>" command; Protocol Start Dialog, w/ list of requirements and 'OK' and 'Abort' buttons.
At start of RunHamilton, delete the schema.ini file from the Hamilton parameters directory;
Add abort button to UserPromptDialog
Experiment ID dialog: "choose XML file to save metadata:"
LMSF Scheduler: Add new command: AddXML/ <parentNode> / <newNode>/ <innerText>
LMSF Scheduler: In SaveXML/ add option argument "not finished" to not add "protocol finished" attribute
LMSF Scheduler: Change "Start/" command to "StartPrompt/"
LMSF Scheduler: Change "UserPrompt/ <title>/ <message>..." comand so that character escape sequences in the <message> are interpretted, this allows multi-line messages (\n) and tabs (\t).
LMSF Scheduler: Add Get/ user/... - to get user ID for metadata; LMSF_Utilities: Add code to automatically create metaList.csv file if it does not exist
LMSF_Utilities: Add saving MetaLists to XML document (MetaIdLists.xml); Protocol/experiment XML document, change projectID from Attribute to Element/Node
LMSF_Utilities: Change GetMetaList() so that it gets the lists from the XML document, MetaIdLists.xml (instead of a bunch of .csv files)
Add parent info and notes (for strains and plasmids) to MetaIdLists.xml
LMSF Scheduler: Add code to better handle AppendXml/ command: SelectXmlDocForAppend() (called by RunAppendXml());
also sets experimentId in dictionary automatically, so that GetExpID/ does not need to be called.
LMSF Scheduler: make sure projectId, experimentId, and data directory get saved to metaDictionary consistently
LMSF Scheduler: In RunAppendXml() check if protocol type already exists and prompt with warning (new AbortAppendOverwriteDialog)
LMSF Scheduler: Add "GetFile/ <file key>/ <file prompt>{/ <file filter>}" command; open user dialog to select file; add file path to dictionary
LMSF Scheduler: Add "If/ <logical test>/ <other valid command>" to step parser, for basic run-time decision making driven by user inputs
LMSF Scheduler: Add User yes/no choice, saves result to dictonary;
Switch Hamilton parameters to Dictionary
Add new projects for creating Gen5 reader: LMSF_Gen5_Reader.dll and LMSF_Gen5.exe (WFP Window)
LMSF_Gen5_Reader: Change PlateStartRead() to read plate in reverse orientation.
LMSF_Gen5_Reader: Add generic exception handling in NewExperiment().
LMSF_Gen5_Reader: Fix issue with folder browser window opening behind everything, by adding SetClientWindow(this) call.
LMSF_Gen5: Set Focusable Property to false for all buttons (to avoid accidental button pushing via keyboard)
LMSF_Gen5_Reader: Add IsReading Property
LMSF_Gen5_Reader: Add checks to make sure IsReading=false before any call to Gen5 methods that should not be called while a read in in progress.
Test over-writing previous experiment file
Move WaitForFinishThenExport() to Gen5Window - so it can more easily manipulate GUI; Add "Read In Progress"/"Reader Idle" status indicator to GUI
On pressing NewExp Button: disable experimentId text box, file/folder buttons, and NewExp button;
add "Close Experiment" button; re-enable controls at end of read;
rename CarrierIn and CarrierOut buttons (previously were openButton and closeButton)
LMSF_Gen5_Reader.CarrierIn(): Retry 3 times on carrier bump error
LMSF_Gen5: Move NewExp, RunExp, CarrierIn, and CarrierOut to stand-alone methods (instead of button click event handlers) so they can be called by remote control TcpListener thread (TBD).
LMSF_Gen5: On NewExp ButtonClick, check if experiment file exists and ask ok to overwrite-
LMSF_Gen5: Check that Read Starts Sucessfully before calling WaitForFinishThenExportAndClose();
LMSF_Gen5: Set output textbox to autoscroll to end of messages
LMSF_Gen5: Add generic error handling try-catch wrapper to all calls to LMSF_Gen5_Reader.dll
LMSF_Gen5: Add IsExperimentQueuedOrRunning property, and move controls enabled state setting to OnPropertyChanged() method (via call to UpdateControlEnabledStatus())
LMSF_Gen5: Add IsConnected property and button to switch between remote and local control
LMSF_Gen5: Add initial TCP Server code with event handlers
Switch SimpleTCP to local source instead of NuGet (might need to mofiy some of it)
LMSF Scheduler: Add ComboBox to select reader for TCP configuration setting, also add variables for use with TCP communication
LMSF Scheduler: Change ConfigureReader() so it could be called by other code: move user interaction (MessageBox) to combo box event handler
LMSF_Gen5_Reader: Add code back to display reader name at top of window
SimpleTCP: Add IsConnected() method
Move WrapTcpMessage() to SimpleTCP.Message class as static method
SimpleTCP: Add CheckMessageHash() method
LMSF_Gen5: Change name of Property IsReadRunning -> IsReaderBusy; also set this property appropriately during CarrierIn(); and CarrierOut();
SimpleTCP: Add UnwrapTcpMessage() method
LMSF_Gen5: Add enum status {Idle, Busy}
LMSF_Gen5: Add message unwrapping and reply to MessageReceived()
LMSF Scheduler: Add SendTcpMessage() method
LMSF_Gen5: change Remote/Local button lables to "Switch to..."
LMSF Scheduler: Add GetConnectedReadersList() method for validation checks
LMSF Scheduler: Add ValidateExpId() method and use it in parsing experiment IDs
LMSF_Utilities: Add IsDirectoryWritable() method
LMSF_Gen5_Reader: combine code for automatic generation of .xpt and export file names into a single method (GetExperimentFilePath()) to keep them consistent
LMSF Scheduler: Add "Gen5/" and "WaitFor/ <reader>/" commands
LMSF_Gen5: Add validation check to experimentID textbox
LMSF_Gen5: Add code to de-queue and run commands that get recieved
LMSF Scheduler: Set ReaderName property correctly - based on computer hostname
LMSF Scheduler: Set IPs for different readers
LMSF_Gen5: Add code run CarrierOut and CarrierIn commands in ParseAndRunCommand()
LMSF_Gen5.Gen5Window: Change readerStatus to property (ReaderStatus) and stop setting it in the IsReaderBusy property setter;
But do set the IsReaderBusy property in the RemoteControl_DoWork() method so that it will appropriately signal to the Scheduler "WaitFor/ <reader>" command.
Also, rename the enum ReaderStatus -> ReaderStatusStates
LMSF Scheduler: Inrease Sleep time in WaitForGen5()
LMSF Scheduler: Add AddOutputText(string txt) method and use it in place of "OutputText +=" - so that everything gets captured to log file
LMSF_Gen5: Change messageQueue type to string so that messageQueue.Contains() works as expected to avoid duplicate commands getting queued
LMSF Scheduler: Add Exception handling in SendTcpMessage(), client.WriteLineAndGetReply() - with excpetion written to log file; any excpetion results in a re-try.
LMSF Scheduler: Add autoscroll to bottom
LMSF Scheduler: Add datetime stamps to each line sent to log file
LMSF Scheduler: Add wrapped message to output text after, "sending message to reader..."
LMSF Scheduler: Add output text after "Running Gen5 Command:"
LMSF Scheduler Gen5/: In validation, when not connected add text about turning on connection on the Scheduler end. Also add label for the relevant control on the GUI
LMSF Scheduler: Change message on connection comboBox - depending on whether or not the reader is currently connected
also, don't change indicator to green if connection isn't made
LMSF_Gen5.Gen5Window: Change property name TextOut -> OutputText, and tempOutTextBox -> outputTextBox, for consistency with Scheduler
LMSF_Gen5.Gen5Window: Add output to log file (and add AddOutputText() method similar to LMSF Scheduler)
add tab to log file lines after timestamp
change log file name endings to "-gen5.trc" and "-lmsf.trc"
Change output message for non-queued/duplicate messages, to make it more clear
Change message hash timestamp format to "fff"
LMSF Scheduler Gen5/<reader>/ RunExp: Add status check to make sure reader actually starts the read before moving on - to avoid having WaitFor/ <reader> return with "Idle" because read had not yet started.
LMSF Scheduler : Make bottom task button area a bit bigger
LMSF_Gen5: Add CarrierIn() step before RunExp() in ParseAndRunCommand() for RunExp command - becasue the Gen5Reader.CarrierIn() has the code to re-try 3 times if there is a bump error
LMSF_Gen5: Add AbortRead button and command
SimpleTCP: Replace DataReceived with DelimiterDataReceived() in WriteLineAndGetReply() so that both message and reply are handled as lines (delimieted by Delimiter = 0x13)
LMSF_Gen5: Add oldMessageQueue - to take messages that have been run - to avoid running duplicates that arrive slowly (after the original has run and been dequeued)
Test and merge into main branch
In GetExpId(), create matching saveDirectory on all connected server computers
For all user dialog boxes in LMSF_Utilities, set IsDefault = false for all buttons
LMSF_Utilities: Don't let get concentration dialog close with empty units field
LMSF_Utilities: Add method GetMetaTypeList(), and change IsValidMetaType()
LMSF Scheduler: With Get/ validation, add list of valid types if "Not a valid metadata type"
LMSF Scheduler: Add numeric comparisons to If/ command, ">, >=, <, <="
LMSF Scheduler: In RunRemoteHamilton(), make sure metaDicitonary is sucessfully exported before sending command to Hamilton
LMSF Scheduler: Add parsing for RemoteHam/ <Hamilton name>/ ReadCounters command
LMSF Scheduler: In RunRemoteHamilton() with ReadCounters command, add wait for method completion then read tip status into dictionary
Hamilton Remote: Add handling of ReadCounters command
Re-write script parsing to use "Command(...)" format instead of "Command/" format
LMSF Scheduler: Enable commas in Set() by re-concatenating arguments
LMSF Scheduler: Change action on SelectComboBox_DropDownClosed() to match new command format
Change Enabled state of input text box to true during run, but set editable state to false
Add "next step" text box to show the next line that will be run
Change status indicator colors in remotes (Hamilton and Gen5): Busy=yellow, Idle=green
In remotes, StatusCheck messages get queued directly to oldMessageQueue
Add parameter to set ping interval on WaitFor()
Add CopyRemoteFiles command to copy files from remote data directories to local data directory
Update help document
Fix validation error with Remote Hamilton(rem, ReadCounters) - validation expects a 3rd parameter
Also, if methodPath ends with "Edit Tip Counters.hsl", also read tip counter file (and change the validation check accordingly)
Add RunScript() command
Read in script file in InitSteps(), just after inputSteps = InputText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
fix bug: if script file not found, protocol aborts but input window is not editable
Make sure user prompts are always on top
In RemoteHam(S-Cell-STAR, ReadCounters), attach method file path to XML node
In send-TCP-message loop, if AbortCalled=true, then exit loop
Also, automatically recconect if send message fails N times.
fix startup status colors on remotes
Add "Are you sure you want to abort?" dialog to make sure protocol does not get accidentally aborted.
ovp variables that are set by Overlord() call, should get appended to the XML\
Test this: In send-TCP-message loop, if AbortCalled=true, then exit loop
Also, automatically reconnect if send message fails N times.
make inputSteps into a list (instead of an array)
Keep comment lines in inputSteps list, but ignore them in ParseStep()
Save XML file every time it the XML is added to; Don't add to xml if abortCalled
Add code to validate and insert manually entered step during pause
Add ExportDictionary and ImportDictionary() commands mechanism for stop/pause, re-write, continue
ExportDictionary() - exports dictionary either to dataDirectory or user specified directory
ImportDictionary() - imports dictionary from user specified file
Add options to handle runtime key-not-found error: user can manually enter key/value into dictionary - and re-run step-
LoadXML() command to go with ImportDictionary() for restarting an experiment
Change so that manually entered step runs when InsertStep button is clicked (if it validates)
Add Math() Command
Enable simple math (+, -, *, /, %) with numeric quantities
Add Error status to ServerStatusStates
Add error reporting (by checking log file at completion of run) to Remote Hamilton
Remote Hamilton run-time error reporting:
When method finishes, Remote Hamilton checks log file for lines that contain "error"
On error, adds lines from log file to errorList
if errorList is not empty, status is set to Error.
The Main Window gets status back as "Error"
Pause, alert user
Add Basic error handling (pause and alert user) in WaitForRemote() method
Take out "Validate with User input..."
Add output script file saved during SaveXML() (usually at the end of the run)
Add parameters to ReadScript to set dictionary values needed by the script
#InsertVariables to indicate where in the script file to insert Set() commands if script file is run via a ReadScript() command
Long identifiers, take out RegEx validation/restriction
Fix bug during CopyRemoteFiles(): don't try to copy files from "local host"
Add GetTimeNow() command to get the current date-time, using DateTime.Now.ToString("HH:mm:ss");
Add date-time handling to Math command - for "+" and "-" operations.
When adding protocol node to XML, add lmsf script file name/path
Also add Input script file-path as comment on first line of output script file
Add "NoUser" optional parameter to AppendXML() so that it can run without user intervention
Fix slow validation with remote connections
TODO:
Check Timer code; the "Time remining" display is not accurate
Add "Hamilton Only/Simulation Mode" - with check box, for running only the Hamilton and RemoteHam steps
Add 2nd checkbox for "Convert RemoteHam to local Hamilton"
Add Gen5 command to get mean OD from the last read?
Add Get(dateTime, timeKey) to get date-time from user
Do not output comments with #?
Add IfKeyExists() or IfNoKey() command
Add new command for Remote Hamilton, GetError(int errorIndex)
This is not a command that needs to be run from the script. It is part of the automated error recovery. So will only be called within the c# code.
sends errorList[errorIndex] back as a message
Need to remove all commas detected in error lines (replace with semi-colons), to avoid issues with TCP message wrapping and unwrapping (which uses commas as separators)
Walk-away error handling:
have a script (.lmsf) file for each error handling situation
new command OnError(<error code>, <error script>)
Combine metadata list/database from multiple computers
Change Overlord variable setting format from "[varibale] value" to "variable = value" (wait for SDK)
error log
Add additional optional parameters to Hamilton() and RemoteHam() that set dictionary keys and write values to XML
Command to read/write from/to the carousel inventory file
Or Carousel inventory that works like Hamilton Tip Counter.
Run-time error handling
Pause and Notify
Retry
Manually change dictionary entry, then retry
Edit command line then retry
Ignore/Continue
Walk-away error handling:
have a script (.lmsf) file for each error handling situation
new command OnError(<error code>, <error script>)
Nested keys
Not necesary: Add else to If(...
Change step list (inputSteps) to Queue or Stack?
Add automatic generation of database with run times for Hamilton and Gen5 methods?
Not necesary: Nested If()
Change arguments passed to BackgroundWorkers to dictionaries, instead of lists.
send email alerts
Test what happens if SaveXML/ is run twice
Make everything thread safe:
First For each class with multiple threads, list all the threads other than the main/GUI thread, and then all the variables/properties accessed by each thread:
LMSF Scheduler.MainWindow
Thread runStepsThread
StepsThreadProc()
IsRunning, get
IsPaused, get
IsOneStep, get
InitSteps()
metaDictionary, set
concDictionary, set
isCollectingXml, set
inputSteps, get, set
InputText, get
stepNum, set
totalSteps, get, set
stepsRunning, set can delete this variable
isValidating, get
OutputText, get, set intentionally not locking this variable
ExperimentFileName, get
logFilePath, get
metaDataFilePath, set
NewLogFile()
logFilePath, set
NewLogFileName()
Step()
AbortCalled, get
IsRunning, set
stepNum, get, set
totalSteps, get
inputSteps, get
isValidating, get
logFilePath, get
IsRunning, set
IsOneStep, set
AddOutputText()
ParseStep()
metaDictionary, set
concDictionary, set
GetConnectedReadersList()
ReaderList, get
readerClients, get
RunOverlord()
WaitingForStepCompletion, set
ovProcess, get, set
isCollectingXml, get
protocolNode, get
RunHamilton()
WaitingForStepCompletion, set
hamProcess, get, set
isCollectingXml, get
protocolNode, get
RunRemoteHamilton()
isCollectingXml, get
protocolNode, get
SendTcpMessage()
readerClients, get
AbortCalled, set
RunGen5()
isCollectingXml, get
protocolNode, get
SendTcpMessage()
readerClients, get
AbortCalled, set
RunTimer()
WaitingForStepCompletion, set
stepTimerDialog, get, set
WaitForOverlord()
WaitingForStepCompletion, get, set
ovProcess, get
isCollectingXml, get
WaitForHamilton()
WaitingForStepCompletion, get, set
hamProcess, get
isCollectingXml, get
WaitForTimer()
WaitingForStepCompletion, get, set
WaitForRemoteProcess()
WaitingForStepCompletion, get, set
isCollectingXml, get
RunNewXml()
RunAppendXml()
RunSaveXml()
RunUserPrompt()
RunUserYesNo()
RunAddXml()
RunSet()
RunGet()
RunGetExpId()
RunGetFile()
RunStartDialog()
BackgroundWorker remoteMonitorWorker
RemoteProcessMonitor_DoWork()
GetRemoteServerStatus()
SendTcpMessage()
readerClients, get
AbortCalled, set
RemoteProcessMonitor_RunWorkerCompleted()
WaitingForStepCompletion, set
BackgroundWorker ovMonitorWorker
OutsideProcessMonitor_DoWork()
outside_Process, get
OutsideProcessMonitor_RunWorkerCompleted()
WaitingForStepCompletion, set
BackgroundWorker hamMonitorWorker
OutsideProcessMonitor_DoWork()
outside_Process, get
OutsideProcessMonitor_RunWorkerCompleted()
WaitingForStepCompletion, set
BackgroundWorker timerMonitorWorker
TimerMonitor_DoWork()
stepTimerDialog, get
TimerMonitor_RunWorkerCompleted()
WaitingForStepCompletion, set
LMSF Scheduler.MainWindow
fields/properties to lock:
WaitingForStepCompletion
At first, it might not seem like this is necessary because there is no place in the code where WaitingForStepCompletion needs to remain locked for more than one line;
but based on this: http://jonskeet.uk/csharp/threads/volatility.shtml, I'm going to put locks on all the flow control booleans.
lock is inside property getter and setter
IsRunning, IsPaused
Message from server (reader/STAR) when finished instead of repeated inquiry from Scheduler
TestReaderCommunication
Add sleep time as optional parameter to WaitFor/
test for graceful closing and/or exit of Scheduler and Gen5Window - with respect to TCP connections
Reader initialization.
Add quick connection test in SimpleTCP.IsConnected()
LMSF Scheduler: on sending command, check if connected first, then reconnect if necessary
Set up maxRetries in Scheduler.SendTcpMessage()
For remote readers, automatically change protocol path?
TCP client/listener
send connection requests from Main LMSF (clients)
LMSF Scheduler - clients
LMSF_Gen5 - server
best bet: "TCP Socket Off-the-shelf" from Code Project
TCP port numbers: 41798-42507 are Unassigned, but Unauthorized Use Known on port 42000
So, use 42222, 42223, 42224..., 42999
Add real-time plotting
Test RunReaderControlCommand()
LMSF Scheduler: Add copy file - to allow user to copy files into experiment data directory
Boolean combinations in If/
control-s shortcut to save
Add cells now/later dialog, w/ 'now', 'later', and 'abort' buttons
Attune front end? 4 buttons: Startup, perf test, run experiment, shutdown
Uses LMSF Scheduler and Utilities code
Open timer dialog near top of screen?
Open Overlord to edit procedure button
control which screen Overlord opens on (screen one preferred)
Comnbine MetaList.csv files from multiple sources (STAR and Overlord Main)
one-line constructors for custom dialogs
Copy functionality from Venus LMSF Utilities library
User input steps: need C# metadata -> xml?
(Probably) Hard-to-do stuff:
Highlight lines in output that have errors (or change text to red)
would require changing to a RichTextBox and more complicated text entry
Still need to figure out Binding - since the idea I had to bind to the Document Property of the Control doesn't work
First, switch the Binding Property from OutPutText to OutPutDocument (Document class)
Then, change return type of the ParseStep() method to Paragraph
Then, in the Step() method, replace the line,
OutputText += ParseStep(stepNum, inputSteps[stepNum]);
with:
OutPutDocument.Blocks.Add(ParseStep(stepNum, inputSteps[stepNum]));
And in the ParseStep() method, at the end,
Paragraph newOutText = new Paragraph();
newOutText.Inlines.Add(outString);
newOutText.FontWeight = FontWeights.Bold; - if validation error
newOutText.Foreground = Brushes.Red; - or Black if passed validation
return newOutText;
Add code to make sure Overlord is started before leaving RunOverlord() - since it is a bit slow to start up
Couldn't figure out how to do that- tabling it for now.
"C:\Program Files (x86)\PAA\Overlord3\Procedures\Common\Peel Plate.ovp" -r -c -v [Plates] 10 [Barcode] "12345678" [Gen5.Protocol.Path] "C:\Gen5 Path..."