SECI  1
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events
BlockInfo.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.IO;
5 using System.Xml.Serialization;
6 
7 namespace Seci.Definitions
8 {
9  public enum ControlType
10  {
12  };
13 
18  public class BlockInfo
19  {
20  //Members
21  private String _blockName;
22  private String _blockUnits;
23  private String _alias;
24  private String _owningComponent;
25  private String _group = "None";
26 
27  private String _nexusName;
28  private String _nexusGroup;
29 
30  private String _parentVi;
31  private String _readControl;
33  private String _writeControl;
34  private String _goButton;
35  private String _waitForControl;
36 
37  private Boolean _underRunControl;
38  private Double _upperLimit;
39  private Double _lowerLimit;
40  private String _runcontrolValue = "";
41  private Boolean _saveSettings;
42  private Boolean _inRange;
43  private Boolean _applyScientificFormatting = true;
44  private Boolean _applyFixedFormatting = false;
45  private int _numDecimalPoints = 3;
46  private String _valueFormatting;
47 
48  private Boolean _blockEnabled;
49  private Boolean _visible = true;
50 
51  private Boolean _logValueToFile;
52  private Single _loggingRate;
53  private Boolean _logChangesNow;
54  private Boolean _logChangesTolerance;
55  private Boolean _logToSharedFile;
56  private String _currentValue;
57  private String _previousValue;
58  private String _previousLogValue;
59  private Double _tolerance;
60  private String _setPointValue;
61  private DateTime _lastLogged;
62  private Boolean _prevReadError = false;
63 
64  public static readonly String ErrorString = "Error";
65 
66  //Properties
67  public String BlockName { get { return _blockName; } set { _blockName = value; } }
68  public String BlockUnits { get { return _blockUnits; } set { _blockUnits = value; } }
69  public String Alias { get { return _alias; } set { _alias = value; } }
70  [XmlIgnore]
71  public String OwningComponent { get { return _owningComponent; } set { _owningComponent = value; } }
72  public String Group { get { return _group; } set { _group = value; } }
73  public String NexusName { get { return _nexusName; } set { _nexusName = value; } }
74  public String NexusGroup { get { return _nexusGroup; } set { _nexusGroup = value; } }
75  public String ParentVI { get { return _parentVi; } set { _parentVi = value; } }
76  public String ReadControl { get { return _readControl; } set { _readControl = value; } }
77  public String WriteControl { get { return _writeControl; } set { _writeControl = value; } }
78  public String GoButton { get { return _goButton; } set { _goButton = value; } }
79  public String WaitForControl { get { return _waitForControl; } set { _waitForControl = value; } }
80  public Boolean UnderRunControl { get { return _underRunControl; } set { _underRunControl = value; } }
81  public Double UpperLimit { get { return _upperLimit; } set { _upperLimit = value; } }
82  public Double LowerLimit { get { return _lowerLimit; } set { _lowerLimit = value; } }
83  public String RunControlValue { get { return _runcontrolValue; } set { _runcontrolValue = value; } }
84  public Boolean InRange { get { return _inRange; } }
85  public Boolean BlockEnabled { get { return _blockEnabled; } set { _blockEnabled = value; } }
86  public Boolean Visible { get { return _visible; } set { _visible = value; } }
87  public Boolean ApplyFormatting { get { return _applyScientificFormatting; } set { _applyScientificFormatting = value; } }
88  public Boolean ApplyFixedFormatting { get { return _applyFixedFormatting; } set { _applyFixedFormatting = value; } }
89  public String ValueFormatting { get { return _valueFormatting; } set { _valueFormatting = value; } }
90  public int NumberDecimalPlaces { get { return _numDecimalPoints; } set { _numDecimalPoints = value; } }
91  public Boolean LogChangesOnly { get { return _logChangesNow; } set { _logChangesNow = value; } }
92  public Boolean LogChangesTolerance { get { return _logChangesTolerance; } set { _logChangesTolerance = value; } }
93  public Double Tolerance { get { return _tolerance; } set { _tolerance = value; } }
94  public Boolean LogValueToFile { get { return _logValueToFile; } set { _logValueToFile = value; } }
95  public Boolean SaveSettings { get { return _saveSettings; } set { _saveSettings = value; } }
96  public Boolean LogToSharedFile { get { return _logToSharedFile; } set { _logToSharedFile = value; } }
97  public Boolean PrevReadError { get { return _prevReadError; } set { _prevReadError = value; } }
98  [XmlIgnore]
99  public ControlType ReadType { get { return _readType; } set { _readType = value; } }
100  public Single LoggingRate
101  {
102  get
103  {
104  return _loggingRate;
105  }
106  set
107  {
108  if (value >= 5)
109  {
110  _loggingRate = value;
111  }
112  else
113  {
114  _loggingRate = 5;
115  }
116  }
117  }
118 
124  [XmlIgnore]
125  public String CurrentValue
126  {
127  get
128  {
129  if (_blockEnabled)
130  {
131  return _currentValue;
132  }
133  else
134  {
135  return "Disabled";
136  }
137  }
138  set
139  {
140  if (_logChangesTolerance)
141  {
142  _currentValue = value;
143 
144  //Only change previous value if new value exceeds tolerance
145  if (_previousValue == null || ExceedsTolerance(_currentValue, _previousValue, _tolerance))
146  {
147  _previousValue = _currentValue;
148  }
149  }
150  else
151  {
152  _previousValue = _currentValue;
153  _currentValue = value;
154  }
155  }
156  }
157 
161  [XmlIgnore]
162  public String FormattedCurrentValue
163  {
164  get
165  {
166  if (CurrentValue == null) return "";
167 
168  if (!_blockEnabled) return "Disabled";
169 
170  if ((_applyScientificFormatting || _applyFixedFormatting) && _readControl.EndsWith("(Numeric)"))
171  {
172  Double temp;
173 
174  if (Double.TryParse(_currentValue, out temp))
175  {
176  return formatValue(temp);
177  }
178  }
179 
180  return _currentValue.Trim();
181  }
182  }
183 
188  [XmlIgnore]
189  public String SetPointValue
190  {
191  get
192  {
193  if (_writeControl != null)
194  {
195  return _setPointValue;
196  }
197  else
198  {
199  return null;
200  }
201  }
202  set
203  {
204  _setPointValue = value;
205  }
206  }
207 
211  [XmlIgnore]
212  public String FormattedSetPointValue
213  {
214  get
215  {
216  if (SetPointValue == null) return "";
217 
218  if (!_blockEnabled) return "";
219 
220  if ((_applyScientificFormatting || _applyFixedFormatting) && _readControl.EndsWith("(Numeric)"))
221  {
222  if (SetPointValue == "0")
223  {
224  return SetPointValue.Trim();
225  }
226 
227  Double temp;
228 
229  if (Double.TryParse(SetPointValue, out temp))
230  {
231  return formatValue(temp);
232  }
233  }
234 
235  return SetPointValue.Trim();
236  }
237  }
238 
239  private String formatValue(Double value)
240  {
241  if (_applyScientificFormatting)
242  {
243  string format = "{0:e" + _numDecimalPoints + "}";
244  if (Math.Abs(value) > 100000f)
245  {
246  return String.Format(format, value);
247  }
248  else if (Math.Abs(value) < 0.0001f && value != 0)
249  {
250  return String.Format(format, value);
251  }
252  else
253  {
254  if (Math.Abs(value) < 1 && value != 0)
255  {
256  //Truncate
257  char[] temp = value.ToString().ToCharArray();
258  string ans = "";
259  int count = 0;
260  for (int i = 0; i < temp.Length; ++i)
261  {
262  if (temp[i] != '0' && temp[i] != '-' && temp[i] != '.')
263  {
264  ++count;
265  }
266 
267  ans += temp[i];
268 
269  if (count >= _numDecimalPoints)
270  {
271  return ans;
272  }
273  }
274 
275  return ans;
276  }
277  else
278  {
279  return Math.Round(value, _numDecimalPoints).ToString();
280  }
281  }
282  }
283  else if (_applyFixedFormatting)
284  {
285  double num = Math.Round(value, _numDecimalPoints);
286 
287  return String.Format("{0:0." + "".PadRight(_numDecimalPoints, '0') + "}", num);
288  }
289  else
290  {
291  return value.ToString();
292  }
293  }
294 
298  public BlockInfo()
299  {
300  //Does nothing
301  }
302 
315  public static Boolean OkayToLog(DateTime timeNow, DateTime lastLogged, Double loggingRate, String currVal, String prevVal, Double tolerance, Boolean onAnyChange, Boolean onToleranceExceeded)
316  {
317  //Log at intervals of x seconds
318  if (!onAnyChange)
319  {
320  //Check that it is time to log; if it is first time then _LastLogged is 01:01:0001, so it will log by default
321  if (timeNow.ToUniversalTime() >= lastLogged.AddSeconds(loggingRate).ToUniversalTime())
322  {
323  if (onToleranceExceeded)
324  {
325  //Has value changed (by more than tolerance)?
326  if (ExceedsTolerance(currVal, prevVal, tolerance))
327  {
328  return true;
329  }
330  }
331  else
332  {
333  return true;
334  }
335  }
336  }
337  //Log changes
338  // if tolerance is exceeded. Tolerance may be zero
339  else if (onToleranceExceeded || onAnyChange)
340  {
341  //Has value changed (by more than tolerance)?
342  if (ExceedsTolerance(currVal, prevVal, tolerance))
343  {
344  return true;
345  }
346  }
347 
348  return false;
349  }
350 
358  public void LogValue(DateTime time, String shortName, String runNumber)
359  {
360  //Note: use UTC for time comparisions as it ignores BST etc.
361  //but the values going into the log files should be BST adjusted
362 
363  //If the block is not enabled do nothing.
364  if (!_blockEnabled || !_logValueToFile) return;
365 
366  if (String.IsNullOrEmpty(runNumber))
367  {
368  //Probably means the DAE is off, so use dummy run number
369  runNumber = "00000000";
370  }
371 
372  if (OkayToLog(time, _lastLogged, _loggingRate, _currentValue, _previousLogValue, _tolerance, _logChangesNow, _logChangesTolerance))
373  {
374  logValue(time, shortName, runNumber);
375  _lastLogged = time;
376  _previousLogValue = _currentValue;
377  }
378  }
379 
387  internal void ForceLogForChangesOnly(DateTime time, String shortName, String runNumber)
388  {
389  if (_logChangesNow || _logChangesTolerance)
390  {
391  logValue(time, shortName, runNumber);
392  }
393  }
394 
401  private void logValue(DateTime time, String shortName, String runNumber)
402  {
403  writeToFile(time, shortName, runNumber);
404 
405  if (Seci.Definitions.Status.LogToDatabase)
406  {
407  //Push into database
408  Seci.Helpers.DatabaseLogger.AddLogValue(convertTimeToString(ref time), _blockName, _currentValue);
409  }
410  }
411 
419  private void writeToFile(DateTime time, String shortName, String runNumber)
420  {
421  String updateTime = convertTimeToString(ref time);
422 
423  //Actually format of filename not implemented yet. Should be ShortnameRunnumber_blockname.txt
424  String fileName = shortName + runNumber + "_" + _blockName + ".txt";
425 
426  if (_blockName != Status.StatusBlockName && (_logToSharedFile || Status.LogAllBlocksToSingleFile))
427  {
428  fileName = shortName + runNumber + ".log";
429  }
430 
431  StreamWriter SW = new StreamWriter("C:\\data\\" + fileName, true);
432 
433  try
434  {
435  if (_blockName != Status.StatusBlockName && (_logToSharedFile || Seci.Definitions.Status.LogAllBlocksToSingleFile))
436  {
437  SW.WriteLine(updateTime + "\t" + _blockName + "\t" + _currentValue);
438  }
439  else
440  {
441  SW.WriteLine(updateTime + "\t" + _currentValue);
442  }
443  }
444  catch (Exception e)
445  {
446  //Throw the error up the chain
447  throw new ArgumentException(e.Message);
448  }
449  finally
450  {
451  SW.Close();
452  }
453  }
454 
460  private static String convertTimeToString(ref DateTime time)
461  {
462  //Convert time to format used in previous versions of SECI
463  System.Globalization.DateTimeFormatInfo myDTFI = new System.Globalization.CultureInfo("en-US", false).DateTimeFormat;
464  String updateTime = time.ToString(myDTFI.SortableDateTimePattern);
465  return updateTime;
466  }
467 
476  public static Boolean ExceedsTolerance(String currValue, String prevValue, Double tolerance)
477  {
478  if (currValue == null)
479  {
480  return false;
481  }
482 
483  //If no previous value (probably a new block or Seci started) then
484  //return true
485  if (prevValue == null)
486  {
487  return true;
488  }
489 
490  //First check if it is a boolean value
491  if (currValue.ToLower() == "true" || currValue.ToLower() == "false")
492  {
493  //Ignore any tolerances on bools as they are pointless
494  if ((currValue.ToLower() == "true" && prevValue.ToLower() == "false") || (currValue.ToLower() == "false" && prevValue.ToLower() == "true"))
495  {
496  //Value has changed
497  return true;
498  }
499  else
500  {
501  //Value has not changed
502  return false;
503  }
504  }
505 
506  //If the tolerance is 0.0 and the value has changed return true
507  if (tolerance == 0.0)
508  {
509  if (prevValue != currValue)
510  {
511  return true;
512  }
513  return false;
514  }
515 
516  //Otherwise, do proper test
517  try
518  {
519  Double curr;
520  Double previous;
521  if (Double.TryParse(currValue, out curr) && Double.TryParse(prevValue, out previous))
522  {
523  //It is a numeric value
524  if (prevValue != null)
525  {
526  if (Math.Abs(curr - previous) >= tolerance)
527  {
528  //Has exceeded tolerance
529  return true;
530  }
531  }
532  else
533  {
534  //Always log the value the first time
535  return true;
536  }
537  }
538  }
539  catch
540  {
541  //probably means that could not convert a value to double
542  //So do nothing as this function will return false by default
543  }
544 
545  //if it gets this far then by default assume it has not exceeded tolerance
546  return false;
547  }
548 
553  public bool OutOfRange()
554  {
555  //Checks whether the block is under run-control and if so is it in range
556  if (_underRunControl == true)
557  {
558  //Check it is not NaN
559  if (_currentValue == "NaN")
560  {
561  _inRange = true;
562  return false;
563  }
564 
565  //Is under run control
566  if (_readType == ControlType.NUMERIC || _readType == ControlType.UNKNOWN)
567  {
568  //In case convert to double fails
569  try
570  {
571  Double low = _lowerLimit;
572  Double high = _upperLimit;
573 
574  if (_lowerLimit > _upperLimit)
575  {
576  low = _upperLimit;
577  high = _lowerLimit;
578  }
579 
580  if ((Convert.ToDouble(_currentValue) < low))
581  {
582  _inRange = false;
583  return true;
584  }
585 
586  if ((Convert.ToDouble(_currentValue) > high))
587  {
588  _inRange = false;
589  return true;
590  }
591 
592  _inRange = true;
593  return false;
594 
595  //Check range
596  //if ((Convert.ToDouble(_currentValue) >= _lowerLimit) && (Convert.ToDouble(_currentValue) <= _upperLimit))
597  //{
598  // //In range
599  // _inRange = true;
600  // return false;
601  //}
602  //else
603  //{
604  // //Out of range
605  // _inRange = false;
606  // return true;
607  //}
608  }
609  catch
610  {
611  _inRange = true;
612  return false;
613  }
614  }
615  else if (_readType == ControlType.STRING || _readType == ControlType.BOOLEAN)
616  {
617  if (_currentValue.ToLower().Trim() == _runcontrolValue.ToLower().Trim())
618  {
619  //In range
620  _inRange = true;
621  return false;
622  }
623  else
624  {
625  //Out of range
626  _inRange = false;
627  return true;
628  }
629  }
630 
631  _inRange = true;
632  return false;
633  }
634  else
635  {
636  //Not under run control, so return false as it is technically in range
637  _inRange = true;
638  return false;
639  }
640  }
641 
648  public void SetRunControlLimits(Boolean enabled, Double low, Double high)
649  {
650  //make sure low is less than high
651  if (low > high)
652  {
653  _lowerLimit = high;
654  _upperLimit = low;
655  }
656  else
657  {
658  _lowerLimit = low;
659  _upperLimit = high;
660  }
661 
662  SetRunControl(enabled);
663  }
664 
671  public void SetRunControlLimits(Boolean enabled, String value)
672  {
673  SetRunControl(enabled);
674  _runcontrolValue = value;
675  }
676 
681  public void SetRunControl(Boolean enabled)
682  {
683  _underRunControl = enabled;
684  }
685 
690  public object Clone()
691  {
692  // Only need a shallow copy of this class
693  return MemberwiseClone();
694  }
695  }
696 }
void SetRunControlLimits(Boolean enabled, Double low, Double high)
Method for setting the numeric run-control limits.
Definition: BlockInfo.cs:648
String _readControl
VI on which it appears.
Definition: BlockInfo.cs:31
void SetRunControlLimits(Boolean enabled, String value)
Method for setting the run-control limit for a single non-numeric value Note: data collection will pa...
Definition: BlockInfo.cs:671
String _currentValue
Log the data to a files that contains data from other blocks.
Definition: BlockInfo.cs:56
Double _upperLimit
Under run-control?
Definition: BlockInfo.cs:38
This class is used for storing the information for any blocks that are created and provides methods f...
Definition: BlockInfo.cs:18
Boolean _logValueToFile
Is the block visible?
Definition: BlockInfo.cs:51
DateTime _lastLogged
The current requested value.
Definition: BlockInfo.cs:61
String _waitForControl
Button to push after setting.
Definition: BlockInfo.cs:35
Double _tolerance
The last value LOGGED to file. Needed for log on change.
Definition: BlockInfo.cs:59
Boolean _logChangesNow
Rate at which block value is logged to file.
Definition: BlockInfo.cs:53
String _nexusName
The group this block belongs to.
Definition: BlockInfo.cs:27
void writeToFile(DateTime time, String shortName, String runNumber)
Method for actually writing to file. The filename is of the form &quot;ShortNameRunNumber_BlockName.txt&quot;.
Definition: BlockInfo.cs:419
Class for holding the standard run-time settings for SECI. A large percentage of the information held...
Definition: Status.cs:12
static Boolean LogAllBlocksToSingleFile
Definition: Status.cs:116
bool OutOfRange()
Check whether the block has exceeded the run-control settings.
Definition: BlockInfo.cs:553
Boolean _inRange
Whether the run-control settings should be saved.
Definition: BlockInfo.cs:42
String _writeControl
The type of the read control.
Definition: BlockInfo.cs:33
Boolean _logToSharedFile
Log changes, but only if the value exceeds the tolerance.
Definition: BlockInfo.cs:55
static Boolean OkayToLog(DateTime timeNow, DateTime lastLogged, Double loggingRate, String currVal, String prevVal, Double tolerance, Boolean onAnyChange, Boolean onToleranceExceeded)
Checks whether to log the block value. Note: public for the purposes of testing
Definition: BlockInfo.cs:315
String _previousValue
The latest value of the block.
Definition: BlockInfo.cs:57
Single _loggingRate
Log to file?
Definition: BlockInfo.cs:52
String _owningComponent
Alias.
Definition: BlockInfo.cs:24
String _blockUnits
Name of block.
Definition: BlockInfo.cs:22
void logValue(DateTime time, String shortName, String runNumber)
Method for calling the appropriate method for logging the value.
Definition: BlockInfo.cs:401
Double _lowerLimit
Upper limit for run-control.
Definition: BlockInfo.cs:39
static String StatusBlockName
Definition: Status.cs:118
String _nexusGroup
NeXus name.
Definition: BlockInfo.cs:28
String formatValue(Double value)
Definition: BlockInfo.cs:239
BlockInfo()
Standard Constructor - necessary for XML serialization.
Definition: BlockInfo.cs:298
Boolean _saveSettings
Non-numeric run-control value.
Definition: BlockInfo.cs:41
String _parentVi
NeXus group.
Definition: BlockInfo.cs:30
String _goButton
Control that is written to.
Definition: BlockInfo.cs:34
static String convertTimeToString(ref DateTime time)
Method for converting a DateTime to the format need for log files
Definition: BlockInfo.cs:460
Boolean _underRunControl
Control to wait for before returning (i.e. motion light).
Definition: BlockInfo.cs:37
object Clone()
Clone method (only a shallow copy).
Definition: BlockInfo.cs:690
Boolean _logChangesTolerance
Just log changes when they occur.
Definition: BlockInfo.cs:54
Boolean _blockEnabled
How many decimal points to show (deprecated)
Definition: BlockInfo.cs:48
String _alias
Units.
Definition: BlockInfo.cs:23
void SetRunControl(Boolean enabled)
Method for enabling and disabling run-control.
Definition: BlockInfo.cs:681
static Boolean ExceedsTolerance(String currValue, String prevValue, Double tolerance)
Check whether the current value has changed by an amount greater than the set tolerance. Note: is public for testing purposes
Definition: BlockInfo.cs:476
ControlType _readType
Control for reading current value.
Definition: BlockInfo.cs:32
String _setPointValue
This value represents how much a value has to change for it to be logged.
Definition: BlockInfo.cs:60
String _previousLogValue
Last value - used to check whether value changed.
Definition: BlockInfo.cs:58
void LogValue(DateTime time, String shortName, String runNumber)
Method for logging the current value of the block. The block is only logged to file if the value sati...
Definition: BlockInfo.cs:358