333 lines
22 KiB
C#
333 lines
22 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using DTS.Common.Classes.Sensors;
|
|||
|
|
|
|||
|
|
namespace DTS.SensorDB.TSF
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// handles the sensor channel information section of the TSF
|
|||
|
|
/// can contain
|
|||
|
|
/// datachan,rack,mod,chan,descrip,s/n,offsetlow,offsethigh,calmode,calstep(ohm/volt),shuntval(eu),proptoext,sens(mv/eu or mv/v/eu),gain,extvolt,EU,filter,invert,zeroref,desiredmaxrange,commentfield,caldate,Offset?,InitialEU,sensorID,ISOcode,IRTRACC exponent,sensor category,desired max range scaling,C0,C1,C2,C3,C4,C5
|
|||
|
|
/// these appear to be only analog sensors
|
|||
|
|
/// </summary>
|
|||
|
|
public class TSFSensorChannelInformationSection
|
|||
|
|
{
|
|||
|
|
private const string SECTION_START_HEADER = "---- Start Sensor Channel Information ----";
|
|||
|
|
private const string COLUMNS_HEADER = "datachan,rack,mod,chan,descrip,s/n,offsetlow,offsethigh,calmode,calstep(ohm/volt),shuntval(eu),proptoext,sens(mv/eu or mv/v/eu),gain,extvolt,EU,filter,invert,zeroref,desiredmaxrange,commentfield,caldate,Offset?,InitialEU,sensorID";
|
|||
|
|
private const string COLUMNS_HEADER_POLY = "C0,C1,C2,C3,C4,C5";
|
|||
|
|
private const string SECTION_END_HEADER = "---- End Sensor Channel Information ----";
|
|||
|
|
|
|||
|
|
private List<TSFSensorEntry> _entries = new List<TSFSensorEntry>();
|
|||
|
|
public TSFSensorEntry[] Entries
|
|||
|
|
{
|
|||
|
|
get => _entries.ToArray();
|
|||
|
|
set => _entries = new List<TSFSensorEntry>(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public TSFSensorChannelInformationSection() { }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// reads the section from the TSF
|
|||
|
|
/// assumes currentline points to the start of the section
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="lines"></param>
|
|||
|
|
/// <param name="currentLine"></param>
|
|||
|
|
/// <param name="errors"></param>
|
|||
|
|
public void ReadFrom(List<string> lines, ref int currentLine, ref List<ReadTSFError> errors)
|
|||
|
|
{
|
|||
|
|
// READ IN SENSOR CHANNEL VALUES
|
|||
|
|
if (currentLine == lines.Count) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_UNEXPECTED_EOF, currentLine)); return; }
|
|||
|
|
var sectionHeader = lines[currentLine++];
|
|||
|
|
if (sectionHeader != SECTION_START_HEADER)
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.SENSORCHANNELSECTION_INVALIDHEADER, currentLine, sectionHeader));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentLine == lines.Count)
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_UNEXPECTED_EOF, currentLine));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
var columnHeader = lines[currentLine++];
|
|||
|
|
var hasPolynomials = false;
|
|||
|
|
if (columnHeader.Contains(COLUMNS_HEADER))
|
|||
|
|
{
|
|||
|
|
// Valid header
|
|||
|
|
hasPolynomials = columnHeader.Contains(COLUMNS_HEADER_POLY);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// Invalid Header
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.SENSORCHANNELSECTION_INVALIDCOLUMNHEADER, currentLine, columnHeader));
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var done = false;
|
|||
|
|
var sensorEntries = new List<TSFSensorEntry>();
|
|||
|
|
var invariant = System.Globalization.CultureInfo.InvariantCulture;
|
|||
|
|
#region Process entries
|
|||
|
|
while (!done)
|
|||
|
|
{
|
|||
|
|
if (currentLine == lines.Count) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_UNEXPECTED_EOF, currentLine)); return; }
|
|||
|
|
var line = lines[currentLine++];
|
|||
|
|
if (!line.Contains("End Sensor Channel Information"))
|
|||
|
|
{
|
|||
|
|
var tokens = line.Split(',');
|
|||
|
|
|
|||
|
|
var entry = new TSFSensorEntry();
|
|||
|
|
|
|||
|
|
for (var iCurField = 0; iCurField < tokens.Length; iCurField++)
|
|||
|
|
{
|
|||
|
|
var s = tokens[iCurField];
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var field = (TSFSensorEntry.Fields)iCurField;
|
|||
|
|
switch (field)
|
|||
|
|
{
|
|||
|
|
case TSFSensorEntry.Fields.caldate:
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var dateTokens = s.Split('_');
|
|||
|
|
entry.CalDate = new DateTime(Convert.ToInt32(dateTokens[2], invariant), Convert.ToInt32(dateTokens[0], invariant), Convert.ToInt32(dateTokens[1], invariant));
|
|||
|
|
}
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_CALDATE, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.calmode:
|
|||
|
|
{
|
|||
|
|
entry.CalMode = new CalMode(s);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.calstep:
|
|||
|
|
try { entry.CalStep = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_CALSTEP, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.chan:
|
|||
|
|
try { entry.Chan = Convert.ToInt32(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_CHAN, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.commentfield: entry.CommentField = s; break;
|
|||
|
|
case TSFSensorEntry.Fields.datachan:
|
|||
|
|
try { entry.DataChan = Convert.ToInt32(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_DATACHAN, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.descrip:
|
|||
|
|
entry.Description = s;
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.desiredmaxrange:
|
|||
|
|
try { entry.DesiredMaxRange = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_DESIREDMAXRANGE, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.desiredmaxrangescaling:
|
|||
|
|
try { entry.DesiredMaxRangeScaling = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_DESIREDMAXRANGESCALING, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.EU: entry.EU = s; break;
|
|||
|
|
case TSFSensorEntry.Fields.extvolt:
|
|||
|
|
try { entry.ExtVolt = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_EXTVOLT, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.filter:
|
|||
|
|
{
|
|||
|
|
double d;
|
|||
|
|
if (!double.TryParse(s, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out d))
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_FILTER, currentLine, s));
|
|||
|
|
}
|
|||
|
|
else { entry.Filter = d; }
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.gain:
|
|||
|
|
try { entry.Gain = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_GAIN, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.InitialEU:
|
|||
|
|
try { entry.InitialEU = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_INITIALEU, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.invert: entry.Invert = !(s == "0" || s == "N" || s == "F"); break;
|
|||
|
|
case TSFSensorEntry.Fields.IRTRACCexponent:
|
|||
|
|
try { entry.IRTRACCexponent = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_IRTRACCEXPONENT, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.ISOcode:
|
|||
|
|
// The TDC SIF ISOcode feild is notoriously abused with holding non-iso information and cannot be trusted to be unique
|
|||
|
|
// This if statement catches some easy to identify signs of abuse and an empty ISO code
|
|||
|
|
if (s.Count() != (new IsoCode(string.Empty)).StringRepresentation.Count() // http://fogbugz/fogbugz/default.asp?9254
|
|||
|
|
|| s.Equals("0000000000000000"))
|
|||
|
|
{
|
|||
|
|
// Stomp on the incorrect ISO Code from the import because we cant trust it.
|
|||
|
|
s = string.Empty;
|
|||
|
|
}
|
|||
|
|
entry.ISOCode = s;
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.mod:
|
|||
|
|
try { entry.Module = Convert.ToInt32(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_MODULE, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.Offset:
|
|||
|
|
{
|
|||
|
|
switch (s)
|
|||
|
|
{
|
|||
|
|
case "0":
|
|||
|
|
case "F":
|
|||
|
|
case "N": entry.RemoveOffset = false; break;
|
|||
|
|
case "1":
|
|||
|
|
case "T":
|
|||
|
|
case "Y": entry.RemoveOffset = true; break;
|
|||
|
|
default:
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_OFFSET, currentLine, s));
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.offsethigh:
|
|||
|
|
try { entry.OffsetHigh = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_OFFSETHIGH, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.offsetlow:
|
|||
|
|
try { entry.OffsetLow = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_OFFSETLOW, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.proptoext: entry.ProportionalToExcitation = !(s == "0" || s == "N" || s == "F"); break;
|
|||
|
|
case TSFSensorEntry.Fields.rack:
|
|||
|
|
try { entry.Rack = Convert.ToInt32(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_RACK, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.sens:
|
|||
|
|
try { entry.Sensitivity = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_SENSITIVITY, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.sensorcategory:
|
|||
|
|
{
|
|||
|
|
switch (s)
|
|||
|
|
{
|
|||
|
|
case "0": entry.SensorCategory = SensorInformationFile.TDCSensorCategory.Normal; break;
|
|||
|
|
case "1": entry.SensorCategory = SensorInformationFile.TDCSensorCategory.POT; break;
|
|||
|
|
case "2": entry.SensorCategory = SensorInformationFile.TDCSensorCategory.IRTracc; break;
|
|||
|
|
case "3": entry.SensorCategory = SensorInformationFile.TDCSensorCategory.Polynomial; break;
|
|||
|
|
default:
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_SENSORCATEGORY, currentLine, s));
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.sensorID:
|
|||
|
|
if (s.Equals("NONE")) { s = string.Empty; }
|
|||
|
|
entry.SensorId = s;
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.serialNumber:
|
|||
|
|
if (sensorEntries.Select(x => x.SerialNumber).Contains(s))
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_DUPLICATESERIALNUMBER, currentLine, s));
|
|||
|
|
}
|
|||
|
|
if (string.IsNullOrEmpty(entry.Description))
|
|||
|
|
{
|
|||
|
|
entry.Description = s;
|
|||
|
|
}
|
|||
|
|
entry.SerialNumber = s;
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.shuntval:
|
|||
|
|
try { entry.ShuntValue = Convert.ToDouble(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_SHUNTVALUE, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.zeroref:
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
entry.ZeroRef = new ZeroRef(s);
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALID_ZEROREF, currentLine, s));
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.C0:
|
|||
|
|
case TSFSensorEntry.Fields.C1:
|
|||
|
|
case TSFSensorEntry.Fields.C2:
|
|||
|
|
case TSFSensorEntry.Fields.C3:
|
|||
|
|
case TSFSensorEntry.Fields.C4:
|
|||
|
|
case TSFSensorEntry.Fields.C5:
|
|||
|
|
// Nothing to do yet.
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
throw new NotSupportedException("TSFFile::ReadTSF unknown field: " + field);
|
|||
|
|
}
|
|||
|
|
if (true == hasPolynomials)
|
|||
|
|
{
|
|||
|
|
switch (field)
|
|||
|
|
{
|
|||
|
|
case TSFSensorEntry.Fields.C0:
|
|||
|
|
try { entry.C0 = double.Parse(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_C0, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.C1:
|
|||
|
|
try { entry.C1 = double.Parse(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_C1, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.C2:
|
|||
|
|
try { entry.C2 = double.Parse(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_C2, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.C3:
|
|||
|
|
try { entry.C3 = double.Parse(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_C3, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.C4:
|
|||
|
|
try { entry.C4 = double.Parse(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_C4, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
case TSFSensorEntry.Fields.C5:
|
|||
|
|
try { entry.C5 = double.Parse(s, invariant); }
|
|||
|
|
catch (Exception) { errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSORCHANNEL_INVALID_C5, currentLine, s)); }
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
//errors.Add("TSF_INVALID_SENSOR_CHANNEL_INFO_FIELD" + iCurField.ToString());
|
|||
|
|
errors.Add(new ReadTSFError(ReadTSFError.TSF_ERRORS.TSF_SENSOR_CHANNEL_INVALIDFIELD, currentLine, iCurField.ToString()));
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sensorEntries.Add(entry);
|
|||
|
|
//tdc has some additional logic to do some scaling over what the desired max range is ... we don't do that yet ...
|
|||
|
|
/*
|
|||
|
|
// Store unscaled desired max range values, and then scale.
|
|||
|
|
Sensor_UnscaledDesiredMaxRange[r][m][c] = Sensor_DesiredMaxRange[r][m][c];
|
|||
|
|
Sensor_DesiredMaxRange[r][m][c] *= Sensor_DesiredMaxRangeScaling;
|
|||
|
|
|
|||
|
|
if (0.0 == Sensor_IRTRACC_Exponent[r][m][c])
|
|||
|
|
{
|
|||
|
|
Sensor_IRTRACC_Exponent[r][m][c] = IRTRACC_DEFAULT_EXPONENT;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// DETERMINE GAIN BASED ON DESIRED MAX RANGE
|
|||
|
|
DetermineMaxRangeandGain(r, m, c, Sensor_DesiredMaxRange[r][m][c], &gain[3], &gain[5], &range[3], &range[5]);
|
|||
|
|
if(IsG5 (Rack_SN[r])) //G5
|
|||
|
|
{
|
|||
|
|
Sensor_Gain[r][m][c]=gain[5];
|
|||
|
|
}
|
|||
|
|
else //PRO
|
|||
|
|
{
|
|||
|
|
Sensor_Gain[r][m][c]=gain[3];
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
}
|
|||
|
|
else { done = true; }
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
Entries = sensorEntries.ToArray();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|