RegisterReaders.SerialStream component added, to be tested, ver. 2.18.909

This commit is contained in:
Milan Hanajik
2018-06-01 09:52:24 +02:00
parent 775af25d1b
commit 5d4dedcb25
14 changed files with 1921 additions and 3 deletions
@@ -0,0 +1,267 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.Globalization;
using System.Text;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public class DatastreamFrame
{
///
/// Strobed value
///
public static decimal TestStartTimestampDec;
///
/// Stored values
///
public FrameFlags Flags;
public DateTime DateTime; /// From PC
public float RefFlow; /// [m3/h]
public int Counter;
const int MaxLength = 256;
public char[] Data = new char[MaxLength];
public int Length;
public byte CheckSum;
public UInt32 VolumeRaw;
public Int64 VolumeRawExt;
public UInt32 Timestamp;
public Int64 TimestampExt;
///
/// Calculated values
///
public double Volume(double scalingFactor) { return (double)VolumeRawExt / scalingFactor; }
public decimal TimestampDec() { return (decimal)TimestampExt / (decimal)8192; }
public double VolumeDelta(double scalingFactor, DatastreamFrame previous) { return (previous == null) ? 0 : Volume(scalingFactor) - previous.Volume(scalingFactor); }
public decimal TimeDelta() { return TimestampDec() - TestStartTimestampDec; }
public string Label()
{
if (Flags == FrameFlags.OK_TestStart) return "#### start test ####";
else if (Flags == FrameFlags.OK_TestEnd) return "#### end of test ####";
else return string.Empty;
}
static DatastreamFrame()
{
}
public DatastreamFrame()
{
}
/// <summary>
/// Parses optical telegram and returns OptoTelegramRaw object
/// </summary>
/// <description>
/// Create a configuration structure from a complete byte array
///
/// Telegram description:
///
/// AAAAAA[tab]BBBB[tab]CCCC[tab]DDDDDD[tab]EEEE[tab]FFFFFFFF[tab]GG[cr][lf] (42 bytes)
///
/// Data Comment Type Calculate to decimal
/// ----------------------------------------------------------------
/// AAAAAA EMF Int24 Value * 0.000000333
/// BBBB Magnetic field Int16 Value
/// CCCC Flow Int16 Value * 0.225 * Scalig factor
/// DDDDDD Volume Int24 Value / 16000 * Scaling factor
/// EEEE Impedance Int16 Value
/// FFFFFFFF Timestamp Uint32 Value / 8192
/// GG Checksum Byte
/// ----------------------------------------------------------------
///
/// Example:
/// FFFFFE 51EA 0000 65324E 0087 F6319DFF 86
/// FFDD3A 51F9 0000 65324E 0088 F631A60B 45
/// ...
/// </description>
/// <param name="data">A complete byte array data</param>
/// <returns>true = telegram OK, false = telegram NOK</returns>
public bool UpdateFromString(string frame, FrameFormat ff, int counter, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast)
{
DateTime = DateTime.Now;
Counter = counter;
RefFlow = (float)Sequences.ProcessData.RefFlow.Val;
if ((frame == null)
|| (frame.Length < ff.FrameLength)
|| (frame[ff.FrameLength - 2] != '\r')
|| (frame[ff.FrameLength - 1] != '\n'))
{
Flags = FrameFlags.InvalidFrame;
return false;
}
Length = frame.Length;
for (int i = 0; i < Math.Min(MaxLength, frame.Length); i++) Data[i] = frame[i];
bool f1 = UInt32.TryParse(frame.Substring(ff.VolumeFieldStart, ff.VolumeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
bool f2 = UInt32.TryParse(frame.Substring(ff.TimeFieldStart, ff.TimeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
bool f3 = byte.TryParse(frame.Substring(ff.FrameLength - 4, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
bool allOk = f1 && f2 && f3;
Flags = allOk ? FrameFlags.OK : FrameFlags.InvalidFrame;
///
/// Cope with 'VolumeRaw' overflow
///
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & ff.VolumeWindowMask) | VolumeRaw);
if (Math.Abs(uncorrected - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected + ff.VolumeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected - ff.VolumeWrapIncrement;
}
else
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
///
/// Cope with 'Timestamp' overflow
///
uncorrected = (Int64)(((UInt64)timestampExtLast & ff.TimeWindowMask) | Timestamp);
if (Math.Abs(uncorrected - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected + ff.TimeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected - ff.TimeWrapIncrement;
}
else
{
TimestampExt = timestampExtLast = uncorrected;
}
return allOk;
}
/// <summary>
/// Alternative to UpdateFromString(...) when data are flushed
/// </summary>
public bool UpdateFromStringDummy(string frame, FrameFormat ff)
{
DateTime = DateTime.Now;
RefFlow = (float)Sequences.ProcessData.RefFlow.Val;
if ((frame == null)
|| (frame.Length < ff.FrameLength)
|| (frame[ff.FrameLength - 2] != '\r')
|| (frame[ff.FrameLength - 1] != '\n'))
{
Flags = FrameFlags.InvalidFrame;
return false;
}
return true;
}
public void SetFlags(FrameFlags flags)
{
this.Flags = flags;
}
public string ToString(double scalingFactor, DatastreamFrame previous)
{
if (Flags == FrameFlags.SyncError)
{
return "Sychronization error";
}
else if (Flags == FrameFlags.InvalidFrame)
{
return "Invalid telegram";
}
else /// if (flags == OptoTelegramFlags.OK / OptoTelegramFlags.OK_TestStart / OptoTelegramFlags.OK_TestEnd)
{
StringBuilder sb = new StringBuilder(MaxLength);
for (int i = 0; i < Math.Min(MaxLength, Length - 2); i++) sb.Append(Data[i]);
return string.Format("{0}:{1}:{2}.{3}\t{4} : {5} Volume={6} Time={7} {8}",
DateTime.Hour.ToString("D2"),
DateTime.Minute.ToString("D2"),
DateTime.Second.ToString("D2"),
DateTime.Millisecond.ToString("D4"),
Counter,
sb,
VolumeRaw.ToString("X6"),
Timestamp.ToString("X8"),
Label());
}
}
/// <summary>
/// Filter RefFlow data in an array of OptoTelegramRaw objects by a FIR filter:
///
/// kSize = 5, kSize2 = 2
///
/// i k
/// ---------------------------------------------------------------------------
/// 0 -5 filtered[0] = data[0]
/// 1 -4 filtered[1] = data[1]
/// 2 -3 filtered[2] = data[0]*k[0] + ... + data[4]*k[4]
/// 3 -2 filtered[3] = data[1]*k[0] + ... + data[5]*k[4]
/// 4 -1 filtered[4] = data[2]*k[0] + ... + data[6]*k[4]
/// 5 0 data[0] = filtered[0], filtered[0] = data[3]*k[0] + ... + data[7]*k[4]
/// 6 1 data[1] = filtered[1], filtered[1] = data[4]*k[0] + ... + data[8]*k[4]
/// 7 ...
/// </summary>
/// <param name="optoData">array of OptoTelegramRaw objects</param>
/// <param name="optoDataCount">number of objects to process</param>
public static void FIRFilterFlow(DatastreamFrame[] optoData, int optoDataCount)
{
float[] kernel = new float[] { 0.1f, 0.2f, 0.4f, 0.2f, 0.1f };
int kSize = kernel.Length;
int kSize2 = kernel.Length / 2;
float[] filtered = new float[kSize];
for (int i = 0; i < optoDataCount; i++)
{
int k = i - kSize;
if (k >= 0) optoData[k].RefFlow = filtered[i % kSize];
if (i < kSize2 || i >= optoDataCount - kSize2)
{
filtered[i % kSize] = optoData[i].RefFlow;
}
else
{
float weoightedSum = 0;
for (int j = -kSize2; j <= kSize2; j++)
weoightedSum += optoData[i + j].RefFlow * kernel[j + kSize2];
filtered[i % kSize] = weoightedSum;
}
}
for (int k = optoDataCount - kSize; k < optoDataCount; k++)
{
if (k >= 0) optoData[k].RefFlow = filtered[k % kSize];
}
}
}
}
@@ -0,0 +1,42 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public enum StreamType
{
None = 0,
Iperl = 1,
Flexible = 2,
Count /// Number of stream types
}
public enum FieldFormat
{
None = 0,
HexadecimalWindow = 1,
Hexadecimal = 2,
Decimal = 3,
Count
}
public enum FrameFlags : byte
{
OK = 0,
OK_TestStart,
OK_TestEnd,
InvalidFrame, /// Wrong frame format of checksum error
SyncError,
}
public enum DatastreamState
{
Read,
Flush,
}
}
@@ -0,0 +1,26 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public class Factory : IComponentFactory
{
public string ClassName { get { return this.GetType().Namespace.Substring(17); } }
public void ResetStaticProperties() { SerialStream.ResetStaticProperties(); }
public IComponent DummyComponent() { return new SerialStream(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new SerialStream(cfg); }
public IComponentCfg DefaultConfig() { return new SerialStreamCfg(this.GetType().Namespace.Substring(17), this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(SerialStreamCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public class FrameFormat
{
public int FrameLength; /// Frame length in characters/bytes, 0 = unknown
public readonly Config.Unit VolumeUnits;
public readonly double VolumeScaleFactor; /// Volume =
public readonly int VolumeFieldStart; /// Start of the volume field: 0-based index of the first character, -1 = no volume field in the frame
public readonly int VolumeFieldEnd; /// End of the volume field: 0-based index of the last character
public readonly FieldFormat VolumeFieldFormat; /// Hexadecimal or Decimal
public readonly Config.Unit TimeUnits;
public readonly double TimeScaleFactor; /// Time =
public readonly int TimeFieldStart; /// Start of the time field: 0-based index of the first character, -1 = no time field in the frame
public readonly int TimeFieldEnd; /// End of the time field: 0-based index of the last character
public readonly FieldFormat TimeFieldFormat; /// Hexadecimal or Decimal
///
/// Calculated in constructor
///
public readonly int VolumeFieldLength;
public readonly UInt64 VolumeWindowMask;
public readonly Int64 VolumeWrapIncrement;
public readonly Int64 VolumeWrapThreshold;
public readonly int TimeFieldLength;
public readonly UInt64 TimeWindowMask;
public readonly Int64 TimeWrapIncrement;
public readonly Int64 TimeWrapThreshold;
public FrameFormat(int frameLength,
Config.Unit volumeUnits, double volumeScaleFactor,
int volumeFieldStart, int volumeFieldEnd, FieldFormat volumeFieldFormat,
Config.Unit timeUnits, double timeScaleFactor,
int timeFieldStart, int timeFieldEnd, FieldFormat timeFieldFormat)
{
FrameLength = frameLength;
VolumeUnits = volumeUnits;
VolumeScaleFactor = volumeScaleFactor;
VolumeFieldStart = volumeFieldStart;
VolumeFieldEnd = volumeFieldEnd;
VolumeFieldFormat = volumeFieldFormat;
TimeUnits = timeUnits;
TimeScaleFactor = timeScaleFactor;
TimeFieldStart = timeFieldStart;
TimeFieldEnd = timeFieldEnd;
TimeFieldFormat = timeFieldFormat;
VolumeFieldLength = VolumeFieldEnd - VolumeFieldStart + 1;
if (volumeFieldFormat == FieldFormat.HexadecimalWindow &&
volumeFieldStart >= 0 && VolumeFieldLength >= 1 && VolumeFieldLength <= 8)
{
VolumeWindowMask = 0xFFFFFFFFFFFFFFFFUL << (4 * VolumeFieldLength);
VolumeWrapIncrement = 1L << (4 * VolumeFieldLength);
VolumeWrapThreshold = 1L << (4 * VolumeFieldLength - 1);
}
TimeFieldLength = TimeFieldEnd - TimeFieldStart + 1;
if (volumeFieldFormat == FieldFormat.HexadecimalWindow &&
volumeFieldStart >= 0 && TimeFieldLength >= 1 && TimeFieldLength <= 8)
{
TimeWindowMask = 0xFFFFFFFFFFFFFFFFUL << (4 * TimeFieldLength);
TimeWrapIncrement = 1L << (4 * TimeFieldLength);
TimeWrapThreshold = 1L << (4 * TimeFieldLength - 1);
}
}
}
}
@@ -0,0 +1,20 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public class FrameReceivedEventArgs : EventArgs
{
public string Data;
public FrameReceivedEventArgs(string data)
{
this.Data = data;
}
}
}
@@ -0,0 +1,287 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.IO;
using System.Xml.Serialization;
using Config.Entities;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public class ProcParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public StreamType StreamType; /// Enumerated stream type
public int FrameLength; /// Frame length in characters/bytes, 0 = unknown
public double FrameFrequency; /// Number of frames per second, 0 = unknown
public Config.Unit VolumeUnits;
public double VolumeScaleFactor; /// Volume =
public int VolumeFieldStart; /// Start of the volume field: 0-based index of the first character, -1 = no volume field in the frame
public int VolumeFieldEnd; /// End of the volume field: 0-based index of the last character
public FieldFormat VolumeFieldFormat; /// Hexadecimal or Decimal
public Config.Unit TimeUnits;
public double TimeScaleFactor; /// Time =
public int TimeFieldStart; /// Start of the time field: 0-based index of the first character, -1 = no time field in the frame
public int TimeFieldEnd; /// End of the time field: 0-based index of the last character
public FieldFormat TimeFieldFormat; /// Hexadecimal or Decimal
public override void InitializeAll()
{
/// Values are for iPerl DN15 in data stream mode at 8 Hz
StreamType = StreamType.Flexible;
FrameLength = 42;
FrameFrequency = 8;
VolumeUnits = Config.Unit.l;
VolumeScaleFactor = 16000;
VolumeFieldStart = 17;
VolumeFieldEnd = 22;
VolumeFieldFormat = FieldFormat.HexadecimalWindow;
TimeUnits = Config.Unit.s;
TimeScaleFactor = 8192;
TimeFieldStart = 29;
TimeFieldEnd = 36;
TimeFieldFormat = FieldFormat.HexadecimalWindow;
}
string[] paramNames = new string[]
{
"Stream type",
"Frame Length",
"Frame Frequency",
"Volume Units",
"Volume Scale Factor",
"Volume Field Start",
"Volume Field End",
"Volume Field Format",
"Time Units",
"Time Scale Factor",
"Time Field Start",
"Time Field End",
"Time Field Format",
};
public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; }
public override string ToString(int i)
{
switch (i)
{
case 0: return StreamType.ToString();
case 1: return FrameLength.ToString();
case 2: return FrameFrequency.ToString();
case 3: return VolumeUnits.ToDescription();
case 4: return VolumeScaleFactor.ToString();
case 5: return VolumeFieldStart.ToString();
case 6: return VolumeFieldEnd.ToString();
case 7: return VolumeFieldFormat.ToString();
case 8: return TimeUnits.ToDescription();
case 9: return TimeScaleFactor.ToString();
case 10: return TimeFieldStart.ToString();
case 11: return TimeFieldEnd.ToString();
case 12: return TimeFieldFormat.ToString();
default: return string.Empty;
}
}
public void UpdateParam(int i, string strValue)
{
switch (i)
{
case 0:
for (StreamType st = 0; st < StreamType.Count; st++)
{
if (st.ToString().Equals(strValue)) { StreamType = st; return; }
}
break;
case 1: FrameLength = int.Parse(strValue); return;
case 2: FrameFrequency = Utils.ParseUDouble(strValue); return;
case 3:
for (Config.Unit u = 0; u < Config.Unit.Count; u++)
{
if (Config.Units.IsQuantity(u, Config.Quantity.Volume) && u.ToDescription().Equals(strValue))
{
VolumeUnits = u;
return;
}
}
break;
case 4: VolumeScaleFactor = Utils.ParseSDouble(strValue); return;
case 5: VolumeFieldStart = int.Parse(strValue); return;
case 6: VolumeFieldEnd = int.Parse(strValue); return;
case 7:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) { VolumeFieldFormat = ff; return; }
}
break;
case 8:
for (Config.Unit u = 0; u < Config.Unit.Count; u++)
{
if (Config.Units.IsQuantity(u, Config.Quantity.Time) && u.ToDescription().Equals(strValue))
{
TimeUnits = u;
return;
}
}
break;
case 9: TimeScaleFactor = Utils.ParseSDouble(strValue); return;
case 10: TimeFieldStart = int.Parse(strValue); return;
case 11: TimeFieldEnd = int.Parse(strValue); return;
case 12:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) { TimeFieldFormat = ff; return; }
}
break;
default: return;
}
}
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
int iDummy;
double fDummy;
switch (i)
{
case 0:
for (StreamType st = 0; st < StreamType.Count; st++)
{
if (st.ToString().Equals(strValue)) return true;
}
break;
case 1:
if (int.TryParse(strValue, out iDummy) && iDummy >= 0 && iDummy <= 8000) return true;
break;
case 2:
if (Utils.TryParseUDouble(strValue, out fDummy) && fDummy <= 1000.0f) return true;
break;
case 3:
for (Config.Unit u = 0; u < Config.Unit.Count; u++)
{
if (Config.Units.IsQuantity(u, Config.Quantity.Volume) && u.ToDescription().Equals(strValue))
{
return true;
}
}
break;
case 4: return Utils.TryParseSDouble(strValue, out fDummy);
case 5: return (int.TryParse(strValue, out iDummy) && (iDummy >= -1));
case 6: return (int.TryParse(strValue, out iDummy) && (iDummy >= 0));
case 7:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) return true;
}
break;
case 8:
for (Config.Unit u = 0; u < Config.Unit.Count; u++)
{
if (Config.Units.IsQuantity(u, Config.Quantity.Time) && u.ToDescription().Equals(strValue))
{
return true;
}
}
break;
case 9: return Utils.TryParseSDouble(strValue, out fDummy);
case 10: return (int.TryParse(strValue, out iDummy) && (iDummy >= -1));
case 11: return (int.TryParse(strValue, out iDummy) && (iDummy >= 0));
case 12:
for (FieldFormat ff = 0; ff < FieldFormat.Count; ff++)
{
if (ff.ToString().Equals(strValue)) return true;
}
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(ProcParams prms)
{
prms.StreamType = this.StreamType;
prms.FrameLength = this.FrameLength;
prms.FrameFrequency = this.FrameFrequency;
prms.VolumeUnits = this.VolumeUnits;
prms.VolumeScaleFactor = this.VolumeScaleFactor;
prms.VolumeFieldStart = this.VolumeFieldStart;
prms.VolumeFieldEnd = this.VolumeFieldEnd;
prms.VolumeFieldFormat = this.VolumeFieldFormat;
prms.TimeUnits = this.TimeUnits;
prms.TimeScaleFactor = this.TimeScaleFactor;
prms.TimeFieldStart = this.TimeFieldStart;
prms.TimeFieldEnd = this.TimeFieldEnd;
prms.TimeFieldFormat = this.TimeFieldFormat;
}
public IParamsProvider Clone()
{
ProcParams pars = new ProcParams();
CopyContentTo(pars);
return pars;
}
public override void UpdateFromDbEntity(ComponentProcedure dbEntity)
{
if (dbEntity == null) return;
try
{
ProcParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as ProcParams;
procedureParamsEntity = dbEntity;
componentName = dbEntity.CmpntName;
procedure = dbEntity.Procedure;
if (tmp != null) tmp.CopyContentTo(this);
}
catch
{
}
}
public ProcParams()
{
}
public ProcParams(bool initialize)
{
if (initialize) InitializeAll();
}
public ProcParams(ComponentProcedure procParamsEntity, string componentName, Procedure procedure)
{
this.procedureParamsEntity = procParamsEntity;
this.componentName = componentName;
this.procedure = procedure;
}
}
}
@@ -0,0 +1,594 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.IO;
using System.IO.Ports;
using log4net;
using Config.Entities;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
/// <summary>
/// This component = instance of this class is a placeholder for a combined main watermeter
/// </summary>
public class SerialStream : ComponentBase, IDevice, GenericDevices.IRegisterReader, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SerialStream));
public override string ToString() { return string.Format("RegisterReaders.SerialStream({0})", Cfg.ToString(1)); }
readonly SerialStreamCfg myCfg;
public Config.Entities.RegisterReaderType RegisterReaderType { get { return Config.Entities.RegisterReaderType.DataStream; } }
public double PulsesPerLtr { get { return 1000.0; } }
public double LtrsPerPulse { get { return 1 / PulsesPerLtr; } }
///
/// Wrappers for procedure parameters
///
public StreamType StreamType { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.StreamType : StreamType.None; } }
public int FrameLength { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.FrameLength : 0; } }
public double FrameFrequency { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.FrameFrequency : 0; } }
public Config.Unit VolumeUnits { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.VolumeUnits : Config.Unit.l; } }
public double VolumeScaleFactor { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.VolumeScaleFactor : 1; } }
public int VolumeFieldStart { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.VolumeFieldStart : 0; } }
public int VolumeFieldEnd { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.VolumeFieldEnd : 0; } }
public FieldFormat VolumeFieldFormat { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.VolumeFieldFormat : FieldFormat.None; } }
public Config.Unit TimeUnits { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.TimeUnits : Config.Unit.s; } }
public double TimeScaleFactor { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.TimeScaleFactor : 1; } }
public int TimeFieldStart { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.TimeFieldStart : 0; } }
public int TimeFieldEnd { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.TimeFieldEnd : 0; } }
public FieldFormat TimeFieldFormat { get { return (myCfg.ProcParams != null) ? myCfg.ProcParams.TimeFieldFormat : FieldFormat.None; } }
public bool CommFailed
{
get { return commFailed; }
set { commFailed = value; }
}
bool commFailed;
/// <summary>
/// Passed to OptoTelegramRaw.UpdateFromString(...)
/// </summary>
Int64 volumeRawExtLast;
Int64 timestampExtLast;
///
/// Required for IRegisterReader interface
///
public int WMPulses { get { return wmPulses; } }
public int WMRefPulses { get { return wmRefPulses; } }
public double WMVolume { get { return wmVolume; } }
public double BeginWMState { get { return beginWMState; } }
public double EndWMState { get { return endWMState; } }
public double WMTestTime { get { return wmTestTime; } }
double beginWMState;
double endWMState;
double wmVolume;
int wmPulses;
int wmRefPulses;
double wmTestTime;
/// <summary> Name set by the test, to be used as a part of the opto-data log file name </summary>
public string TestName;
/// <summary> Name set by the test, to be used as a part of the opto-data log file name </summary>
public string BenchName;
///
/// Volume of water from the opto telegram
///
private Int64 lastVolumeRaw; /// Last read raw volume
private double volumeLtr; ///
private double volumeLtr0;
public double VolumeLtrStart; /// Test start volume for metrology
public double VolumeLtrEnd; /// Test end volume for metrology
public double VolumeLtrRef; /// Reference volume or metrology
double volumeLtrEnd1; /// auxiliary buffer1 to keep the end volume before test stops
double volumeLtrEnd2; /// auxiliary buffer2 to keep the end volume before test stops
double volumeLtrEnd3; /// auxiliary buffer3 to keep the end volume before test stops
///
/// Timestamp from the opto telegram
///
bool lastTimestampValid;
private Int64 lastTimestamp;
private double timestampSec;
private double timestampSec0;
public bool NoSamples { get { return (timestampSecEnd - timestampSecStart) < float.Epsilon; } }
public double TimestampSecStart { get { return timestampSecStart; } }
public double TimestampSecEnd { get { return timestampSecEnd; } }
double timestampSecStart;
double timestampSecEnd;
double timestampSecEnd1;
double timestampSecEnd2;
double timestampSecEnd3;
private int frameIx;
public int TestStartFrameIx;
public int TestEndFrameIx;
DatastreamFrame[] datastreamFrames;
const int MaxDatastreamFramesCount = 40000;
int datastreamFramesCount;
string datastreamLogFileName;
DatastreamFrame toBeFlushed;
int flushedFramesCount;
public int FlushedFramesCount
{
get { return flushedFramesCount; }
set { flushedFramesCount = lastFlushedFramesCount = lastFlushedFramesCount_1 = value; }
}
int lastFlushedFramesCount_1;
int lastFlushedFramesCount;
public int FlushedFramesDelta
{
get
{
int retval = Math.Max(flushedFramesCount - lastFlushedFramesCount, lastFlushedFramesCount - lastFlushedFramesCount_1);
lastFlushedFramesCount_1 = lastFlushedFramesCount;
lastFlushedFramesCount = flushedFramesCount;
return retval;
}
}
///
/// Opto serial port and worker thread related private variables
///
private SerialPort serialPort;
public SerialStream()
{
}
public SerialStream(Generic.IComponentCfg cfg)
: base(cfg)
{
ClearData();
myCfg = cfg as SerialStreamCfg;
log.Debug(this.ToString());
}
/// <summary>
/// Clear data related to a specific water meter
/// </summary>
public void ClearData()
{
commFailed = false;
datastreamFramesCount = 0;
}
public void Initialize()
{
ClearData();
if (DebugLevel == DebugMode.Normal)
{
datastreamParsingEnabled = false;
currentFrameFormat = new FrameFormat(FrameLength,
VolumeUnits, VolumeScaleFactor,
VolumeFieldStart, VolumeFieldEnd, VolumeFieldFormat,
TimeUnits, TimeScaleFactor,
TimeFieldStart, TimeFieldEnd, TimeFieldFormat);
/// Allocate memory for opto-data from iPerl
datastreamFrames = new DatastreamFrame[MaxDatastreamFramesCount];
for (int i = 0; i < MaxDatastreamFramesCount; i++) datastreamFrames[i] = new DatastreamFrame();
toBeFlushed = new DatastreamFrame();
flushedFramesCount = 0;
synchronized = false;
synchronized2 = false;
partOfTelegram = string.Empty;
/// Prepare serial port
serialPort = new SerialPort(string.Format("COM{0}", myCfg.ComPortNr),
myCfg.BaudRate,
myCfg.Parity,
myCfg.DataBits,
myCfg.StopBits);
serialPort.Handshake = myCfg.Handshake;
serialPort.Open();
}
}
public void RunDeviceBefore()
{
if (DebugLevel == DebugMode.Normal)
{
try
{
if (datastreamParsingEnabled)
ReadDatastream(DatastreamState.Read, currentFrameFormat);
else
ReadDatastream(DatastreamState.Flush, currentFrameFormat);
}
catch (Exception e)
{
DebugLevel = DebugMode.FailureDuringOperation;
log.FatalFormat("Opto-data serial port failure : {0}", e.Message);
if (e.InnerException != null)
{
log.FatalFormat("InnerMessage : {0}", e.InnerException.Message);
}
}
}
else if (DebugLevel == DebugMode.FailureDuringOperation)
{
}
}
public void RunDeviceAfter() { }
public void StopDevice()
{
try
{
if (DebugLevel == DebugMode.Normal && serialPort != null)
{
serialPort.Close();
serialPort = null;
}
}
catch
{
}
}
public void StopDevice2() { }
/// <summary>
/// Events: Event.ReadRegisterDone, Event.Error
/// </summary>
/// <returns>ReadWaterMeter instance reference casted to IOperaton</returns>
public IOperation ReadRegisterOp()
{
return this;
}
/// <summary>
/// Clear data/counters related to a specific tests
/// </summary>
public void Clear()
{
sampleNr = 0;
volumeLtr = 0;
volumeLtr0 = 0;
timestampSec = 0;
timestampSec0 = 0;
ReadPulses();
}
public void TestCompleted()
{
/// TODO: Implement
}
int sampleNr; /// This is to determine when the test start sample should be taken
/// <summary>Start this operation</summary>
public void Start()
{
Clear();
/// Reset opto data
datastreamFramesCount = 0;
TestStartFrameIx = 0;
TestEndFrameIx = 0;
/// File name
int digitIx = Name.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
string position = (digitIx >= 0) ? Name.Substring(digitIx) : string.Empty;
datastreamLogFileName = string.Format("{0}_{1}_{2}.txt",
StateMachine.CycleStartTimeStamp.ToString("HHmmss"),
position,
TestName);
StartParsingDatastream(new FrameFormat(FrameLength,
VolumeUnits, VolumeScaleFactor,
VolumeFieldStart, VolumeFieldEnd, VolumeFieldFormat,
TimeUnits, TimeScaleFactor,
TimeFieldStart, TimeFieldEnd, TimeFieldFormat));
}
/// <summary>Run this operation</summary>
/// <returns>eventDone</returns>
public Event Run()
{
sampleNr++;
ReadPulses();
if (sampleNr == 4)
{
/// Take the test start sample
VolumeLtrStart = volumeLtr;
timestampSecStart = timestampSec;
TestStartFrameIx = frameIx;
}
/// Shift data in pipelines
VolumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd3 = volumeLtrEnd2;
volumeLtrEnd2 = volumeLtrEnd1;
volumeLtrEnd1 = volumeLtr;
timestampSecEnd = timestampSecEnd3;
timestampSecEnd3 = timestampSecEnd2;
timestampSecEnd2 = timestampSecEnd1;
timestampSecEnd1 = timestampSec;
TestEndFrameIx = frameIx - 3;
return Event.ReadRegisterDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
if (TestStartFrameIx > 0 && TestStartFrameIx < datastreamFrames.Length && datastreamFrames[TestStartFrameIx].Flags == FrameFlags.OK)
{
datastreamFrames[TestStartFrameIx].Flags = FrameFlags.OK_TestStart;
DatastreamFrame.TestStartTimestampDec = datastreamFrames[TestStartFrameIx].TimestampDec();
}
if (TestEndFrameIx > 0 && TestEndFrameIx < datastreamFrames.Length && datastreamFrames[TestEndFrameIx].Flags == FrameFlags.OK)
{
datastreamFrames[TestEndFrameIx].Flags = FrameFlags.OK_TestEnd;
}
StopParsingDatastream();
DatastreamFrame.FIRFilterFlow(datastreamFrames, datastreamFramesCount);
SaveDatastreamLog();
}
void SaveDatastreamLog()
{
string directory = string.Format("C:\\TBF\\ProcessData\\{0}\\{1}\\{2}\\",
StateMachine.CycleStartTimeStamp.ToString("yy"),
StateMachine.CycleStartTimeStamp.ToString("MM"),
StateMachine.CycleStartTimeStamp.ToString("dd"));
string datastreamLogPathName = directory + datastreamLogFileName;
try
{
Directory.CreateDirectory(directory);
double scalFact = ScalingFactor();
using (TextWriter datastreamLogFile = new StreamWriter(datastreamLogPathName))
{
datastreamLogFile.WriteLine(datastreamFrames[0].ToString(scalFact, null));
for (int i = 1; i < datastreamFramesCount; i++) datastreamLogFile.WriteLine(datastreamFrames[i].ToString(scalFact, datastreamFrames[i - 1]));
datastreamLogFile.Close();
}
}
catch (Exception exc)
{
File.Delete(datastreamLogPathName);
log.ErrorFormat(string.Format("Error writing into file {0}", datastreamLogPathName));
log.ErrorFormat(string.Format("Exception message: {0}", exc.Message));
}
}
void ReadPulses()
{
beginWMState = volumeLtr0;
endWMState = volumeLtr;
wmVolume = Math.Abs(endWMState - beginWMState);
wmPulses = (int)(wmVolume * (double)PulsesPerLtr + 0.5);
wmRefPulses = StateMachine.ControlBoard.EtPulses(0);
wmTestTime = timestampSec - timestampSec0;
}
bool datastreamParsingEnabled;
FrameFormat currentFrameFormat; /// Set by StartParsingDatastream()
/// <summary> Flush internal buffers and start parsing the opto serial port data </summary>
void StartParsingDatastream(FrameFormat ff)
{
currentFrameFormat = ff;
datastreamParsingEnabled = true;
}
/// <summary> Stop parsig the opto serial port data </summary>
void StopParsingDatastream()
{
datastreamParsingEnabled = false;
}
///
/// Variables storing the context of serial port data parsing (ReadOptoSerialPort(...))
///
bool synchronized;
bool synchronized2;
string partOfTelegram;
/// <summary>
/// 9600 Bd, 8 data bits, 1 stop bit, no parity
///
/// Telegram description:
///
/// AAAAAA[tab]BBBB[tab]CCCC[tab]DDDDDD[tab]EEEE[tab]FFFFFFFF[tab]GG[cr][lf] (42 bytes)
///
/// Example:
/// FFFFFE 51EA 0000 65324E 0087 F6319DFF 86
/// FFDD3A 51F9 0000 65324E 0088 F631A60B 45
/// ...
/// </summary>
/// <param name="streamState">OptoState.Read or OptoState.Flush</param>
void ReadDatastream(DatastreamState streamState, FrameFormat ff)
{
int nrBytes = serialPort.BytesToRead;
if (nrBytes > 0)
{
char[] buffer = new char[nrBytes];
serialPort.Read(buffer, 0, nrBytes);
string received = new string(buffer);
string allRcvd = partOfTelegram + received;
while (true)
{
int pos = allRcvd.IndexOf("\r\n");
if (pos < 0)
{
/// No CR+LF found, wait for more characters in the next invocation
partOfTelegram = allRcvd;
return;
}
else
{
// CR+LF found
if (streamState == DatastreamState.Read)
{
if (pos < FrameLength - 2)
{
/// CR+LF found too early, truncate the beginning incl CR+LF and keep scanning in this loop
allRcvd = allRcvd.Substring(pos + 2);
if (synchronized)
{
datastreamFrames[datastreamFramesCount].Counter = datastreamFramesCount;
datastreamFrames[datastreamFramesCount++].SetFlags(FrameFlags.SyncError);
}
synchronized = true;
}
// CR+LF found and (pos >= OptoTelegramRaw.Length - 2)
else if (datastreamFrames[datastreamFramesCount].UpdateFromString(allRcvd.Substring(pos - ff.FrameLength + 2), ff, datastreamFramesCount, ref volumeRawExtLast, ref timestampExtLast))
{
OptoTelegramRreceived(datastreamFramesCount++, synchronized2);
synchronized2 = synchronized;
allRcvd = allRcvd.Substring(pos + 2);
}
else
{
datastreamFrames[datastreamFramesCount].Counter = datastreamFramesCount;
datastreamFramesCount++;
allRcvd = allRcvd.Substring(pos + 2);
}
}
else /// optoState == SerialStreamState.Flush
{
if (pos < FrameLength - 2)
{
/// CR+LF found too early, truncate the beginning incl CR+LF and keep scanning in this loop
allRcvd = allRcvd.Substring(pos + 2);
synchronized = true;
}
// CR+LF found and (pos >= OptoTelegram.Length - 2)
else if (toBeFlushed.UpdateFromStringDummy(allRcvd.Substring(pos - ff.FrameLength + 2), ff))
{
flushedFramesCount++;
synchronized2 = synchronized;
allRcvd = allRcvd.Substring(pos + 2);
}
else
{
allRcvd = allRcvd.Substring(pos + 2);
}
}
}
}
//OnFrameReceived(this, new FrameReceivedEventArgs(s));
}
else
{
//OnFrameReceived(this, new FrameReceivedEventArgs("."));
}
}
void OptoTelegramRreceived(int currentIx, bool async)
{
DatastreamFrame optoTelegram = datastreamFrames[currentIx];
frameIx = currentIx;
lastVolumeRaw = volumeRawExtLast;
lastTimestamp = timestampExtLast;
if (volumeLtr == 0 && volumeLtr0 == 0)
{
volumeLtr = (double)lastVolumeRaw * ScalingFactor() / 16000.0;
volumeLtr0 = volumeLtr;
}
else
{
volumeLtr = (double)lastVolumeRaw * ScalingFactor() / 16000.0;
}
if (timestampSec == 0 && timestampSec0 == 0)
{
timestampSec = (double)lastTimestamp / 8192.0;
timestampSec0 = timestampSec;
}
else
{
timestampSec = (double)lastTimestamp / 8192.0;
}
//optoDataLogger.InfoFormat("{0} {1} {2} ltr {3} {4}", optoTelegram, lastTimestamp, lastVolumeRaw.ToString("X8"), timestampSec.ToString("F1"), volumeLtr.ToString("F3"));
}
/// <summary>
/// Called from the state machine when a test is selected and UI needs to be updated.
/// </summary>
public void OnFrameReceived(object sender, FrameReceivedEventArgs args)
{
if (FrameReceivedHandler == null) return;
try { FrameReceivedHandler(sender, args); }
catch (Exception) { }
}
public event EventHandler<FrameReceivedEventArgs> FrameReceivedHandler;
public static double UnitVolume(Config.Unit units, double scaleFactor)
{
if (Config.Units.IsQuantity(units, Config.Quantity.Volume))
{
return Config.Units.ConvertFrom(units, 1.0) * scaleFactor;
}
else
{
return 1.0;
}
}
public double ScalingFactor()
{
return 1.0;
}
}
}
@@ -0,0 +1,63 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.IO.Ports;
using System.Xml.Serialization;
using Config.Entities;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public class SerialStreamCfg : ComponentCfgBase, Generic.IComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(SerialStreamCfg) })[0];
protected override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl() { return new SerialStreamCfgCtrl(); }
///
/// Serialized parameters
///
public int ComPortNr;
public int BaudRate;
public Parity Parity;
public int DataBits;
public StopBits StopBits;
public Handshake Handshake;
///
/// Procedure parameters
///
[XmlIgnore]
public ProcParams ProcParams;
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
public override IParamsProvider CreateProcParamsProvider() { return new ProcParams(true); }
/// Private parameterless constructor invoked by all other (public) constructors
SerialStreamCfg()
{
ProcParams = CreateProcParamsProvider() as ProcParams;
}
public SerialStreamCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = string.Empty;
ComPortNr = 21;
BaudRate = 9600;
Parity = System.IO.Ports.Parity.None;
DataBits = 8;
StopBits = System.IO.Ports.StopBits.One;
Handshake = System.IO.Ports.Handshake.None;
}
public string ToString(int i)
{
return string.Format("{0} Com{1}, {2}Bd, {3}-bits, parity={4}, stopBits={5}, {6}",
Name, ComPortNr, BaudRate, DataBits, Parity, StopBits, Handshake);
}
}
}
@@ -0,0 +1,173 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
using System;
using System.Windows.Forms;
using System.IO.Ports;
using log4net;
using TBF.BenchControl.Generic;
using TBF.Resources;
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
public partial class SerialStreamCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(SerialStreamCfgCtrl));
public bool ShowMore { get { return false; } }
SerialStreamCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as SerialStreamCfg;
Redraw();
}
}
public SerialStreamCfgCtrl()
{
InitializeComponent();
parityComboBox.Items.Add(Parity.None.ToString());
parityComboBox.Items.Add(Parity.Even.ToString());
parityComboBox.Items.Add(Parity.Odd.ToString());
stopBitsComboBox.Items.Add(StopBits.None.ToString());
stopBitsComboBox.Items.Add(StopBits.One.ToString());
stopBitsComboBox.Items.Add(StopBits.OnePointFive.ToString());
stopBitsComboBox.Items.Add(StopBits.Two.ToString());
handshakeComboBox.Items.Add(Handshake.None.ToString());
handshakeComboBox.Items.Add(Handshake.RequestToSend.ToString());
handshakeComboBox.Items.Add(Handshake.XOnXOff.ToString());
}
int GetParityIx(Parity par)
{
if (par == Parity.None) return 0;
if (par == Parity.Even) return 0;
if (par == Parity.Odd) return 0;
return -1;
}
Parity GetParity(string str)
{
if (str.Equals(Parity.None.ToString())) return Parity.None;
if (str.Equals(Parity.Even.ToString())) return Parity.Even;
if (str.Equals(Parity.Odd.ToString())) return Parity.Odd;
return (Parity)(-1);
}
int GetStopBitsIx(StopBits sb)
{
if (sb == StopBits.None) return 0;
if (sb == StopBits.One) return 1;
if (sb == StopBits.OnePointFive) return 2;
if (sb == StopBits.Two) return 3;
return -1;
}
StopBits GetStopBits(string str)
{
if (str.Equals(StopBits.None.ToString())) return StopBits.None;
if (str.Equals(StopBits.One.ToString())) return StopBits.One;
if (str.Equals(StopBits.OnePointFive.ToString())) return StopBits.OnePointFive;
if (str.Equals(StopBits.Two.ToString())) return StopBits.Two;
return (StopBits)(-1);
}
int GetHandshakeIx(Handshake par)
{
if (par == Handshake.None) return 0;
if (par == Handshake.RequestToSend) return 0;
if (par == Handshake.XOnXOff) return 0;
return -1;
}
Handshake GetHandshake(string str)
{
if (str.Equals(Handshake.None.ToString())) return Handshake.None;
if (str.Equals(Handshake.RequestToSend.ToString())) return Handshake.RequestToSend;
if (str.Equals(Handshake.XOnXOff.ToString())) return Handshake.XOnXOff;
return (Handshake)(-1);
}
private void ModbusCfgCtrl_Load(object sender, EventArgs e)
{
nameLabel.Text = Strings.Name;
Redraw();
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
comPortNrTextBox.Text = config.ComPortNr.ToString();
baudRateTextBox.Text = config.BaudRate.ToString();
parityComboBox.Text = config.Parity.ToString();
dataBitsTextBox.Text = config.DataBits.ToString();
stopBitsComboBox.Text = config.StopBits.ToString();
handshakeComboBox.Text = config.Handshake.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
comPortNrTextBox.Enabled = true;
baudRateTextBox.Enabled = true;
parityComboBox.Enabled = true;
dataBitsTextBox.Enabled = true;
stopBitsComboBox.Enabled = true;
handshakeComboBox.Enabled = true;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ComPortNr = int.Parse(comPortNrTextBox.Text);
config.BaudRate = int.Parse(baudRateTextBox.Text);
config.Parity = GetParity(parityComboBox.SelectedItem.ToString());
config.DataBits = int.Parse(dataBitsTextBox.Text);
config.StopBits = GetStopBits(stopBitsComboBox.SelectedItem.ToString());
config.Handshake = GetHandshake(handshakeComboBox.SelectedItem.ToString());
return flags;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
int dummy;
if (!int.TryParse(comPortNrTextBox.Text, out dummy) || dummy < 1 || dummy > 999)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Serial Port Number' is not valid";
}
if (!int.TryParse(baudRateTextBox.Text, out dummy) || dummy < 150 || dummy > 115200)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Baud Rate' is not valid";
}
if (!int.TryParse(dataBitsTextBox.Text, out dummy) || dummy < 7 || dummy > 8)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "'Data Bits' is not valid";
}
return flags;
}
}
}
@@ -0,0 +1,229 @@
///
/// Copyright (c) 2018 Sensus Slovensko a.s.
///
namespace TBF.BenchControl.RegisterReaders.SerialStream
{
partial class SerialStreamCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.comPortNrTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.baudRateLabel = new System.Windows.Forms.Label();
this.baudRateTextBox = new System.Windows.Forms.TextBox();
this.partityLabel = new System.Windows.Forms.Label();
this.dataBitsLabel = new System.Windows.Forms.Label();
this.dataBitsTextBox = new System.Windows.Forms.TextBox();
this.stopBitsLabel = new System.Windows.Forms.Label();
this.handshakeLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.parityComboBox = new System.Windows.Forms.ComboBox();
this.stopBitsComboBox = new System.Windows.Forms.ComboBox();
this.handshakeComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comPortNrTextBox
//
this.comPortNrTextBox.Enabled = false;
this.comPortNrTextBox.Location = new System.Drawing.Point(140, 52);
this.comPortNrTextBox.Name = "comPortNrTextBox";
this.comPortNrTextBox.Size = new System.Drawing.Size(34, 20);
this.comPortNrTextBox.TabIndex = 4;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(29, 55);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(98, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Serial Port Number:";
//
// baudRateLabel
//
this.baudRateLabel.AutoSize = true;
this.baudRateLabel.Location = new System.Drawing.Point(29, 79);
this.baudRateLabel.Name = "baudRateLabel";
this.baudRateLabel.Size = new System.Drawing.Size(58, 13);
this.baudRateLabel.TabIndex = 5;
this.baudRateLabel.Text = "Baud Rate";
//
// baudRateTextBox
//
this.baudRateTextBox.Enabled = false;
this.baudRateTextBox.Location = new System.Drawing.Point(140, 76);
this.baudRateTextBox.Name = "baudRateTextBox";
this.baudRateTextBox.Size = new System.Drawing.Size(130, 20);
this.baudRateTextBox.TabIndex = 6;
//
// partityLabel
//
this.partityLabel.AutoSize = true;
this.partityLabel.Location = new System.Drawing.Point(29, 103);
this.partityLabel.Name = "partityLabel";
this.partityLabel.Size = new System.Drawing.Size(33, 13);
this.partityLabel.TabIndex = 7;
this.partityLabel.Text = "Parity";
//
// dataBitsLabel
//
this.dataBitsLabel.AutoSize = true;
this.dataBitsLabel.Location = new System.Drawing.Point(29, 127);
this.dataBitsLabel.Name = "dataBitsLabel";
this.dataBitsLabel.Size = new System.Drawing.Size(50, 13);
this.dataBitsLabel.TabIndex = 9;
this.dataBitsLabel.Text = "Data Bits";
//
// dataBitsTextBox
//
this.dataBitsTextBox.Enabled = false;
this.dataBitsTextBox.Location = new System.Drawing.Point(140, 124);
this.dataBitsTextBox.Name = "dataBitsTextBox";
this.dataBitsTextBox.Size = new System.Drawing.Size(34, 20);
this.dataBitsTextBox.TabIndex = 10;
//
// stopBitsLabel
//
this.stopBitsLabel.AutoSize = true;
this.stopBitsLabel.Location = new System.Drawing.Point(29, 151);
this.stopBitsLabel.Name = "stopBitsLabel";
this.stopBitsLabel.Size = new System.Drawing.Size(49, 13);
this.stopBitsLabel.TabIndex = 11;
this.stopBitsLabel.Text = "Stop Bits";
//
// handshakeLabel
//
this.handshakeLabel.AutoSize = true;
this.handshakeLabel.Location = new System.Drawing.Point(29, 175);
this.handshakeLabel.Name = "handshakeLabel";
this.handshakeLabel.Size = new System.Drawing.Size(62, 13);
this.handshakeLabel.TabIndex = 13;
this.handshakeLabel.Text = "Handshake";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(140, 28);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(30, 31);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(137, 7);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// parityComboBox
//
this.parityComboBox.Enabled = false;
this.parityComboBox.FormattingEnabled = true;
this.parityComboBox.Location = new System.Drawing.Point(140, 100);
this.parityComboBox.Name = "parityComboBox";
this.parityComboBox.Size = new System.Drawing.Size(130, 21);
this.parityComboBox.TabIndex = 8;
//
// stopBitsComboBox
//
this.stopBitsComboBox.Enabled = false;
this.stopBitsComboBox.FormattingEnabled = true;
this.stopBitsComboBox.Location = new System.Drawing.Point(140, 148);
this.stopBitsComboBox.Name = "stopBitsComboBox";
this.stopBitsComboBox.Size = new System.Drawing.Size(130, 21);
this.stopBitsComboBox.TabIndex = 12;
//
// handshakeComboBox
//
this.handshakeComboBox.Enabled = false;
this.handshakeComboBox.FormattingEnabled = true;
this.handshakeComboBox.Location = new System.Drawing.Point(140, 172);
this.handshakeComboBox.Name = "handshakeComboBox";
this.handshakeComboBox.Size = new System.Drawing.Size(130, 21);
this.handshakeComboBox.TabIndex = 14;
//
// AmbientCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Control;
this.Controls.Add(this.handshakeComboBox);
this.Controls.Add(this.stopBitsComboBox);
this.Controls.Add(this.parityComboBox);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Controls.Add(this.handshakeLabel);
this.Controls.Add(this.stopBitsLabel);
this.Controls.Add(this.dataBitsTextBox);
this.Controls.Add(this.dataBitsLabel);
this.Controls.Add(this.partityLabel);
this.Controls.Add(this.baudRateTextBox);
this.Controls.Add(this.baudRateLabel);
this.Controls.Add(this.comPortNrTextBox);
this.Controls.Add(this.label1);
this.Name = "AmbientCfgCtrl";
this.Size = new System.Drawing.Size(300, 240);
this.Load += new System.EventHandler(this.ModbusCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox comPortNrTextBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label baudRateLabel;
private System.Windows.Forms.TextBox baudRateTextBox;
private System.Windows.Forms.Label partityLabel;
private System.Windows.Forms.Label dataBitsLabel;
private System.Windows.Forms.TextBox dataBitsTextBox;
private System.Windows.Forms.Label stopBitsLabel;
private System.Windows.Forms.Label handshakeLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.ComboBox parityComboBox;
private System.Windows.Forms.ComboBox stopBitsComboBox;
private System.Windows.Forms.ComboBox handshakeComboBox;
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>