399 lines
17 KiB
Plaintext
399 lines
17 KiB
Plaintext
using DTS.Common.Enums;
|
|
using DTS.Common.Enums.DASFactory;
|
|
using DTS.Common.Interface.DASFactory;
|
|
using DTS.Common.Interface.DASFactory.Config;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace DTS.Common.Classes.TMAT
|
|
{
|
|
|
|
/// <summary>
|
|
/// these are all the patterns that represent global keys
|
|
/// </summary>
|
|
public enum TMTGlobalKeys
|
|
{
|
|
[TMTKey("{NAME OF PROGRAM}")] NameOfProgram,
|
|
[TMTKey("{TEST ID}")] TestId,
|
|
[TMTKey("{DAS SERIAL NUMBER}")] DASSerialNumber,
|
|
[TMTKey("{DAS INDEX}")] DASIndex,
|
|
[TMTKey("{DAS SAMPLE RATE}")] DASSampleRate,
|
|
[TMTKey("{TEST TIMESTAMP}")] TestTimeStamp,
|
|
[TMTKey("{DAS BIT RATE}")] DASBitRate,
|
|
[TMTKey("{STREAM TIME FORMAT}")] StreamTimeFormat,
|
|
//FB 26736 Keys for time & data channel Id
|
|
[TMTKey("{UDP STREAM TIME CHANNEL ID}")] UdpStreamTimeChannelId,
|
|
[TMTKey("{UDP STREAM DATA CHANNEL ID}")] UdpStreamDataChannelId,
|
|
//FB 29996 Key for file creation date
|
|
[TMTKey("{CREATE DATE}")] CreateDate,
|
|
//http://manuscript.dts.local/f/cases/37929/Implement-TSRAIR-module-on-off-selection-via-Max-Slice-Enable-system-attribute
|
|
[TMTKey("{NUMBER OF STREAMED CHANNELS}")] NumberOfStreamedChannels,
|
|
[TMTKey("{NUMBER OF CHANNELS PLUS TIME}")] NumberOfChannelsPlusTime,
|
|
[TMTKey("{NUMBER OF BITS PER MINOR FRAME}")] NumberOfBitsPerMinorFrame
|
|
}
|
|
/// <summary>
|
|
/// these are all the patterns that represent channel keys when channels are all part of 1 template
|
|
/// </summary>
|
|
public enum TMTChannelKeys
|
|
{
|
|
[TMTKey("{{CHANNEL {0} HARDWARE CHANNEL NUMBER}}")] HardwareChannelNumber,
|
|
[TMTKey("{{CHANNEL {0} NAME}}")] ChannelName,
|
|
[TMTKey("{{CHANNEL {0} COUPLING MODE}}")] CouplingMode,
|
|
[TMTKey("{{CHANNEL {0} BRIDGE RESISTANCE}}")] BridgeResistance,
|
|
[TMTKey("{{CHANNEL {0} AAF}}")] AAF,
|
|
[TMTKey("{{CHANNEL {0} OFFSET mV}}")] OffsetMV,
|
|
[TMTKey("{{CHANNEL {0} INPUT RANGE}}")] InputRangeMV,
|
|
[TMTKey("{{CHANNEL {0} MAX RANGE EU}}")] MaxRangeEU,
|
|
[TMTKey("{{CHANNEL {0} MIN RANGE EU}}")] MinRangeEU,
|
|
[TMTKey("{{CHANNEL {0} EU}}")] EU,
|
|
[TMTKey("{{CHANNEL {0} SCALEFACTOR EU}}")] ScaleFactorEU,
|
|
[TMTKey("{{CHANNEL {0} OFFSET EU}}")] OffsetEU,
|
|
}
|
|
/// <summary>
|
|
/// these are patterns for channel keys when channels are split into a separate template
|
|
/// </summary>
|
|
public enum TMTChannelKeysEx
|
|
{
|
|
[TMTKey("{CHANNEL NUMBER}")]ChannelNumber,
|
|
[TMTKey("{CHANNEL NAME}")]ChannelName,
|
|
[TMTKey("{CHANNEL OFFSET EU}")]ChannelOffsetEU,
|
|
[TMTKey("{CHANNEL SCALEFACTOR EU}")]ChannelScaleFactorEU,
|
|
[TMTKey("{CHANNEL EU}")]ChannelEU,
|
|
[TMTKey("{CHANNEL MAX RANGE EU}")]ChannelMaxRangeEU,
|
|
[TMTKey("{CHANNEL MIN RANGE EU}")]ChannelMinRangeEU
|
|
}
|
|
/// <summary>
|
|
/// Helper attribute, allows us to associate patterns to enums to make processing file easier
|
|
/// </summary>
|
|
[System.AttributeUsage(System.AttributeTargets.Field)]
|
|
public class TMTKey : System.Attribute
|
|
{
|
|
/// <summary>
|
|
/// the pattern to look for in a line to replace
|
|
/// </summary>
|
|
public string Key { get; set; }
|
|
|
|
public TMTKey(string key)
|
|
{
|
|
Key = key;
|
|
}
|
|
/// <summary>
|
|
/// returns the pattern to look for in a line for a given property
|
|
/// </summary>
|
|
/// <param name="o"></param>
|
|
/// <returns></returns>
|
|
public static string GetKey(TMTGlobalKeys o)
|
|
{
|
|
var mi = o.GetType().GetMember(o.ToString());
|
|
if (mi.Length <= 0) return string.Empty;
|
|
return GetCustomAttribute(mi[0], typeof(TMTKey)) is TMTKey attr ? attr.Key : string.Empty;
|
|
}
|
|
/// <summary>
|
|
/// returns the pattern to look for in a line for a given property
|
|
/// </summary>
|
|
/// <param name="o"></param>
|
|
/// <returns></returns>
|
|
public static string GetKey(TMTChannelKeysEx o)
|
|
{
|
|
var mi = o.GetType().GetMember(o.ToString());
|
|
if (mi.Length <= 0) return string.Empty;
|
|
return GetCustomAttribute(mi[0], typeof(TMTKey)) is TMTKey attr ? attr.Key : string.Empty;
|
|
}
|
|
/// <summary>
|
|
/// returns the pattern to look for in a line for a given channel property
|
|
/// </summary>
|
|
/// <param name="o"></param>
|
|
/// <param name="channelNumber"></param>
|
|
/// <returns></returns>
|
|
public static string GetKey(TMTChannelKeys o, int channelNumber)
|
|
{
|
|
var mi = o.GetType().GetMember(o.ToString());
|
|
if (mi.Length <= 0) return string.Empty;
|
|
if (GetCustomAttribute(mi[0], typeof(TMTKey)) is TMTKey attr)
|
|
{
|
|
return string.Format(attr.Key, channelNumber);
|
|
}
|
|
else
|
|
{
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
}
|
|
public interface ITMTTemplate
|
|
{
|
|
/// <summary>
|
|
/// updates the fields in the file with a given value
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
void UpdateValue(TMTChannelKeysEx key, string value);
|
|
/// <summary>
|
|
/// updates the fields in the file with a given value
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
void UpdateValue(TMTGlobalKeys key, string value);
|
|
|
|
/// <summary>
|
|
/// updates the files in the file with the given value
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="channelNumber"></param>
|
|
void UpdateValue(TMTChannelKeys key, string value, int channelNumber);
|
|
|
|
|
|
/// <summary>
|
|
/// returns all lines in the TMT file
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
string[] GetAllLines();
|
|
}
|
|
|
|
public class TMTTemplate : ITMTTemplate
|
|
{
|
|
/// <summary>
|
|
/// this is the max length of the channel name in a TMT file,
|
|
/// this was done in an effort to keep TMT file length below 4k bytes
|
|
/// 2019-10-10 - DTM increased this to 200 as TMT file length was increased to 16k
|
|
/// </summary>
|
|
private const int TMT_MAX_CHANNEL_LENGTH = 200;
|
|
/// <summary>
|
|
/// does the work to ensure string is of MAX_LENGTH or shorter
|
|
/// </summary>
|
|
/// <param name="s"></param>
|
|
/// <returns></returns>
|
|
public static string TMT_LimitString(string s)
|
|
{
|
|
return s.Substring(0, Math.Min(s.Length, TMT_MAX_CHANNEL_LENGTH));
|
|
}
|
|
/// <summary>
|
|
/// updates the given field in the template with a value
|
|
/// </summary>
|
|
public static void UpdateChannelField(TMTChannelKeysEx key, ITMTTemplate template, int channelIndex,
|
|
float [] ranges, double minEU, double maxEU, string eu, float [] scaleFactors, double adcToEUScalingFactor,
|
|
string channelName2, string offsetEU)
|
|
{
|
|
switch (key)
|
|
{
|
|
case TMTChannelKeysEx.ChannelNumber:
|
|
template.UpdateValue(key, $"{1 + channelIndex}");
|
|
break;
|
|
case TMTChannelKeysEx.ChannelName:
|
|
template.UpdateValue(key, TMT_LimitString(channelName2));
|
|
break;
|
|
case TMTChannelKeysEx.ChannelOffsetEU:
|
|
template.UpdateValue(key, TMT_LimitString(offsetEU));
|
|
break;
|
|
case TMTChannelKeysEx.ChannelScaleFactorEU:
|
|
if (scaleFactors != null)
|
|
{
|
|
template.UpdateValue(key, scaleFactors[channelIndex].ToString("F11"));
|
|
}
|
|
else
|
|
{
|
|
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : adcToEUScalingFactor.ToString("F11"));
|
|
}
|
|
break;
|
|
case TMTChannelKeysEx.ChannelEU:
|
|
template.UpdateValue(key,
|
|
RunTestVariables.MaskEUMetaData ? "---" : eu?.Trim() ?? "");
|
|
break;
|
|
case TMTChannelKeysEx.ChannelMaxRangeEU:
|
|
{
|
|
if ( ranges != null)
|
|
{
|
|
template.UpdateValue(key, ranges[channelIndex].ToString("F0"));
|
|
}
|
|
else { template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : maxEU.ToString("F0")); }
|
|
}
|
|
break;
|
|
case TMTChannelKeysEx.ChannelMinRangeEU:
|
|
{
|
|
if (ranges != null)
|
|
{
|
|
template.UpdateValue(key, (-1 * ranges[channelIndex]).ToString("F0"));
|
|
}
|
|
else
|
|
{
|
|
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
|
minEU.ToString("F0"));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
public static void UpdateGlobalField(IDASCommunication das, TMTGlobalKeys key, ITMTTemplate template,
|
|
IConfigurationData ConfigData,
|
|
String serialNumber,
|
|
ushort? timeChannelId,
|
|
ushort? dataChannelId,
|
|
int dasIndex,
|
|
int bitsPerFrame)
|
|
{
|
|
switch (key)
|
|
{
|
|
case TMTGlobalKeys.NameOfProgram:
|
|
template.UpdateValue(key,
|
|
TMT_LimitString(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name));
|
|
break;
|
|
case TMTGlobalKeys.TestId:
|
|
template.UpdateValue(key, TMT_LimitString(ConfigData.TestID));
|
|
break;
|
|
case TMTGlobalKeys.CreateDate:
|
|
//FB 29996 used the same date format from the template
|
|
template.UpdateValue(key, DateTime.Now.ToString("MM-dd-yyyy"));
|
|
break;
|
|
case TMTGlobalKeys.DASSerialNumber:
|
|
template.UpdateValue(key, serialNumber);
|
|
break;
|
|
// FB 26736 replace time & data channel Ids in template
|
|
case TMTGlobalKeys.UdpStreamDataChannelId:
|
|
if (dataChannelId.HasValue)
|
|
{
|
|
template.UpdateValue(key, dataChannelId.Value.ToString());
|
|
}
|
|
break;
|
|
case TMTGlobalKeys.UdpStreamTimeChannelId:
|
|
if (timeChannelId.HasValue)
|
|
{
|
|
template.UpdateValue(key, timeChannelId.Value.ToString());
|
|
}
|
|
break;
|
|
case TMTGlobalKeys.DASIndex:
|
|
template.UpdateValue(key, dasIndex.ToString());
|
|
break;
|
|
case TMTGlobalKeys.DASSampleRate:
|
|
template.UpdateValue(key, ConfigData.Modules[0].SampleRateHz.ToString());
|
|
break;
|
|
case TMTGlobalKeys.DASBitRate:
|
|
template.UpdateValue(key,
|
|
(ConfigData.Modules[0].SampleRateHz * bitsPerFrame).ToString());
|
|
break;
|
|
case TMTGlobalKeys.StreamTimeFormat:
|
|
// FB15388 Add line "R-1\TTF-1:{TIME FORMAT};" to detail either time format 1 or 2
|
|
// FB 30035 Get stream time format from StreamOut module
|
|
var streamOutModule = Array.Find(ConfigData.Modules, m => m.ModuleType() == DFConstantsAndEnums.ModuleType.StreamOut);
|
|
|
|
if (streamOutModule != null)
|
|
{
|
|
template.UpdateValue(key, streamOutModule.StreamProfile.ToString().Contains(Constants.UDP_STREAM_CH10_TF2) ? "2" : "1");
|
|
}
|
|
|
|
break;
|
|
case TMTGlobalKeys.TestTimeStamp:
|
|
var now = DateTime.Now;
|
|
var timeStamp =
|
|
$"{now.Month:00}-{now.Day:00}-{now.Year:0000}-{now.Hour:00}-{now.Minute:00}-{now.Second:00}";
|
|
template.UpdateValue(key, timeStamp);
|
|
break;
|
|
case TMTGlobalKeys.NumberOfStreamedChannels: template.UpdateValue(key, GetNumberOfStreamedChannels(das).ToString()); break;
|
|
case TMTGlobalKeys.NumberOfChannelsPlusTime: template.UpdateValue(key, (1 + GetNumberOfStreamedChannels(das)).ToString()); break;
|
|
case TMTGlobalKeys.NumberOfBitsPerMinorFrame: template.UpdateValue(key, (32 + 16 * GetNumberOfStreamedChannels(das)).ToString()); break;
|
|
}
|
|
}
|
|
public static int GetNumberOfStreamedChannels(IDASCommunication das)
|
|
{
|
|
if (das is IDASReconfigure reconfigure)
|
|
{
|
|
return GetNumberOfStreamedChannelsReconfigurable(das);
|
|
}
|
|
else { return 6; }
|
|
}
|
|
private static int GetNumberOfStreamedChannelsReconfigurable(IDASCommunication das)
|
|
{
|
|
//for now the TSR AIR is the only reconfigurable streaming devices? we may need to fix this in the future
|
|
switch (das.DASInfo.Modules.Length)
|
|
{
|
|
case 3: return 3; //TSR AIR Lowg only (low g + stream output + UART)
|
|
case 4: return 6; //TSR AIR LowG & High G (low g + high g + stream output + UART)
|
|
case 5: return 9; //TSR AIR LowG, HighG, ARS
|
|
default: return 18; //ALL
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// reads all lines from the file in the given location and prepare to update values
|
|
/// </summary>
|
|
/// <param name="templateLocation"></param>
|
|
public TMTTemplate(string templateLocation)
|
|
{
|
|
if (System.IO.File.Exists(templateLocation))
|
|
{
|
|
_allLines.AddRange(System.IO.File.ReadAllLines(templateLocation));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// constructs a new template with the given lines of content
|
|
/// </summary>
|
|
/// <param name="lines"></param>
|
|
public TMTTemplate(string[] lines)
|
|
{
|
|
_allLines.AddRange(lines);
|
|
}
|
|
/// <summary>
|
|
/// updates the files in the file with a given value
|
|
/// </summary>
|
|
public void UpdateValue(TMTChannelKeysEx key, string value)
|
|
{
|
|
var pattern = TMTKey.GetKey(key);
|
|
for( var i = 0; i < _allLines.Count; i++)
|
|
{
|
|
if (_allLines[i].Contains(pattern))
|
|
{
|
|
_allLines[i] = _allLines[i].Replace(pattern, value);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// updates the fields in the file with a given value
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
public void UpdateValue(TMTGlobalKeys key, string value)
|
|
{
|
|
var pattern = TMTKey.GetKey(key);
|
|
for (int i = 0; i < _allLines.Count; i++)
|
|
{
|
|
if (_allLines[i].Contains(pattern))
|
|
{
|
|
_allLines[i] = _allLines[i].Replace(pattern, value);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// updates the files in the file with the given value
|
|
/// </summary>
|
|
/// <param name="key"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="channelNumber"></param>
|
|
public void UpdateValue(TMTChannelKeys key, string value, int channelNumber)
|
|
{
|
|
var pattern = TMTKey.GetKey(key, channelNumber);
|
|
for (int i = 0; i < _allLines.Count; i++)
|
|
{
|
|
if (_allLines[i].Contains(pattern))
|
|
{
|
|
_allLines[i] = _allLines[i].Replace(pattern, value);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// all lines in the TMT file
|
|
/// </summary>
|
|
private List<string> _allLines = new List<string>();
|
|
|
|
/// <summary>
|
|
/// returns all lines in the TMT file
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string[] GetAllLines()
|
|
{
|
|
return _allLines.ToArray();
|
|
}
|
|
}
|
|
|
|
}
|