364 lines
16 KiB
C#
364 lines
16 KiB
C#
|
|
using DTS.Common.Enums;
|
|||
|
|
using DTS.Common.Enums.DASFactory;
|
|||
|
|
using DTS.Common.Interface.DASFactory;
|
|||
|
|
using DTS.Common.Interface.DASFactory.Config;
|
|||
|
|
using System;
|
|||
|
|
|
|||
|
|
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 43761
|
|||
|
|
[TMTKey("{UDP STREAM UART CHANNEL ID}")] UdpStreamUartChannelId,
|
|||
|
|
[TMTKey("{UDP STREAM UART CHANNEL ID ENABLED}")] UdpStreamUartChannelIdEnabled,
|
|||
|
|
//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,
|
|||
|
|
[TMTKey("{BYTE FORMAT}")]ByteFormat,
|
|||
|
|
[TMTKey("{BYTE FORMAT2}")]ByteFormat2,
|
|||
|
|
[TMTKey("{CHANNEL MIDPOINT}")]ChannelMidPoint
|
|||
|
|
}
|
|||
|
|
/// <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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S101:Types should be named in Acronym", Justification = "<Pending>")]
|
|||
|
|
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, int channelNumber);
|
|||
|
|
/// <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 abstract class TmtBase : 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));
|
|||
|
|
}
|
|||
|
|
private static string ScaleFactorOrOffsetToString(double d)
|
|||
|
|
{
|
|||
|
|
return $"{d:0.0##########}";//F11, but strip trailing zeros
|
|||
|
|
}
|
|||
|
|
/// <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, bool bSigned)
|
|||
|
|
{
|
|||
|
|
switch (key)
|
|||
|
|
{
|
|||
|
|
case TMTChannelKeysEx.ChannelNumber:
|
|||
|
|
template.UpdateValue(key, $"{1 + channelIndex}", channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelName:
|
|||
|
|
template.UpdateValue(key, TMT_LimitString(channelName2), channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelOffsetEU:
|
|||
|
|
template.UpdateValue(key, TMT_LimitString(offsetEU), channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelScaleFactorEU:
|
|||
|
|
if (scaleFactors != null)
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, ScaleFactorOrOffsetToString(scaleFactors[channelIndex]), channelIndex);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : ScaleFactorOrOffsetToString(adcToEUScalingFactor), channelIndex);
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ByteFormat:
|
|||
|
|
template.UpdateValue(key, bSigned?"TWO":"OFF", channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ByteFormat2:
|
|||
|
|
template.UpdateValue(key, bSigned?"2":"B", channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelMidPoint:
|
|||
|
|
template.UpdateValue(key, bSigned?"0":"2500", channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelEU:
|
|||
|
|
template.UpdateValue(key,
|
|||
|
|
RunTestVariables.MaskEUMetaData ? "---" : eu?.Trim() ?? "", channelIndex);
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelMaxRangeEU:
|
|||
|
|
{
|
|||
|
|
if ( ranges != null)
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, ranges[channelIndex].ToString("F0"), channelIndex);
|
|||
|
|
}
|
|||
|
|
else { template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" : maxEU.ToString("F0"), channelIndex); }
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TMTChannelKeysEx.ChannelMinRangeEU:
|
|||
|
|
{
|
|||
|
|
if (ranges != null)
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, (-1 * ranges[channelIndex]).ToString("F0"), channelIndex);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, RunTestVariables.MaskEUMetaData ? "1" :
|
|||
|
|
minEU.ToString("F0"), channelIndex);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public static void UpdateGlobalField(IDASCommunication das, TMTGlobalKeys key, ITMTTemplate template,
|
|||
|
|
IConfigurationData ConfigData,
|
|||
|
|
String serialNumber,
|
|||
|
|
ushort? timeChannelId,
|
|||
|
|
ushort? dataChannelId,
|
|||
|
|
ushort? uartChannelId,
|
|||
|
|
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;
|
|||
|
|
//FB 43761 update tmat file with uart channel id & enable/disable T/F
|
|||
|
|
case TMTGlobalKeys.UdpStreamUartChannelId:
|
|||
|
|
if (uartChannelId.HasValue)
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, uartChannelId.Value.ToString());
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case TMTGlobalKeys.UdpStreamUartChannelIdEnabled:
|
|||
|
|
if (uartChannelId.HasValue)
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, uartChannelId.Value > 0 ? "T" : "F");
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
template.UpdateValue(key, "F");
|
|||
|
|
}
|
|||
|
|
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)
|
|||
|
|
{
|
|||
|
|
if (das.GetHardwareType() == Enums.Hardware.HardwareTypes.SLICE6_AIR_TC)
|
|||
|
|
{
|
|||
|
|
return 24;
|
|||
|
|
}
|
|||
|
|
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
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public abstract void UpdateValue(TMTChannelKeysEx key, string value, int channelNumber);
|
|||
|
|
public abstract void UpdateValue(TMTGlobalKeys key, string value);
|
|||
|
|
public abstract void UpdateValue(TMTChannelKeys key, string value, int channelNumber);
|
|||
|
|
public abstract string[] GetAllLines();
|
|||
|
|
}
|
|||
|
|
}
|