using System;
using System.Collections.Generic;
using System.Linq;
using DTS.Common.Classes.Sensors;
namespace DTS.SensorDB.TSF
{
///
/// 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
///
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 _entries = new List();
public TSFSensorEntry[] Entries
{
get => _entries.ToArray();
set => _entries = new List(value);
}
public TSFSensorChannelInformationSection() { }
///
/// reads the section from the TSF
/// assumes currentline points to the start of the section
///
///
///
///
public void ReadFrom(List lines, ref int currentLine, ref List 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();
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();
}
}
}