Merge branch 'master-2-26-Flex' into master-2-26
This commit is contained in:
commit
a203885c16
@ -4,7 +4,7 @@
|
||||
using System.Collections.Generic;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow.Rest
|
||||
namespace TBF.BenchControl.Output.FlexFlow
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
566
TBF/BenchControl/Output/FlexFlow/FlexFlow.cs
Normal file
566
TBF/BenchControl/Output/FlexFlow/FlexFlow.cs
Normal file
@ -0,0 +1,566 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using log4net;
|
||||
using Config.Entities;
|
||||
using System.Text;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow
|
||||
{
|
||||
public class FlexFlow : ComponentBase, IOperation, GenericDevices.IResultsWriter, GenericDevices.IStartInfoReader, Generic.IDevice
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(FlexFlow));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
FlexFlowCfg flexFlowCfg;
|
||||
|
||||
public string StationName
|
||||
{
|
||||
get
|
||||
{
|
||||
var benchInfo = TBF.BenchControl.Sequences.ProcessData.BenchInfo;
|
||||
return (benchInfo != null) ? benchInfo.TestBenchName : "TestBench";
|
||||
}
|
||||
}
|
||||
|
||||
public string UserId { get { return Users.GlobalData.GetCurrentUserName(); } }
|
||||
|
||||
|
||||
enum Retv
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
}
|
||||
|
||||
enum OpState
|
||||
{
|
||||
None,
|
||||
GetUnitInfosScheduled,
|
||||
GetUnitInfosRunning,
|
||||
SaveResultsScheduled,
|
||||
SaveResultsRunning,
|
||||
}
|
||||
///
|
||||
OpState currentOpState;
|
||||
bool opCompleted;
|
||||
bool anyError;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Watermeters to check at the beginning of the cycle
|
||||
/// </summary>
|
||||
IList<Results.Entities.WaterMeter> waterMeters;
|
||||
|
||||
/// <summary>
|
||||
/// Data (tracing records) to write at the end of cycle
|
||||
/// </summary>
|
||||
Results.Entities.Batch batch;
|
||||
DateTime resultsTimeStamp;
|
||||
string resultsTimeStampStr;
|
||||
|
||||
|
||||
public FlexFlow() {}
|
||||
|
||||
public FlexFlow(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
flexFlowCfg = cfg as FlexFlowCfg;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
currentOpState = OpState.None;
|
||||
resultsTimeStampStr = string.Empty;
|
||||
|
||||
if (flexFlowCfg.DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
/// TODO: Initialize FlexFlow
|
||||
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.FatalFormat("{0} simulated: {1}", Name, this);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// IDevice interface implementation
|
||||
///
|
||||
public void RunDeviceBefore() { }
|
||||
public void RunDeviceAfter() { }
|
||||
///
|
||||
public void StopDevice()
|
||||
{
|
||||
if (flexFlowCfg.DebugLevel != DebugMode.Normal) return;
|
||||
|
||||
/// TODO: Close FlexFlow
|
||||
}
|
||||
public void StopDevice2() {}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads information on start of a cycle, Events: Event.InfoRead
|
||||
/// </summary>
|
||||
/// <param name="waterMeters">Results of water meters</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ReadStartInfoOp(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
if (!flexFlowCfg.CheckPreviousRecords)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.GetUnitInfosRunning) || (currentOpState == OpState.SaveResultsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.waterMeters = waterMeters;
|
||||
currentOpState = OpState.GetUnitInfosScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the test cycle results into a file, Events: Event.ResultsWritten
|
||||
/// </summary>
|
||||
/// <param name="procedure">Procedure to print the results of</param>
|
||||
/// <param name="unsortedResults">Results to write into the file</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ProcessResultsOp(Results.Entities.Batch batch)
|
||||
{
|
||||
if (!flexFlowCfg.SaveResults)
|
||||
{
|
||||
log.WarnFormat("{0} saving results disabled", Name);
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.GetUnitInfosRunning) || (currentOpState == OpState.SaveResultsRunning))
|
||||
{
|
||||
log.WarnFormat("{0} sequence error", Name);
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.batch = batch;
|
||||
this.resultsTimeStamp = batch.EndTime;
|
||||
this.resultsTimeStampStr = batch.EndTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
currentOpState = OpState.SaveResultsScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
var oriOpState = currentOpState;
|
||||
|
||||
if (currentOpState == OpState.GetUnitInfosScheduled)
|
||||
{
|
||||
currentOpState = OpState.GetUnitInfosRunning;
|
||||
}
|
||||
else if (currentOpState == OpState.SaveResultsScheduled)
|
||||
{
|
||||
currentOpState = OpState.SaveResultsRunning;
|
||||
}
|
||||
|
||||
opCompleted = false;
|
||||
anyError = false;
|
||||
log.WarnFormat("{0} Start() completed, op.state {1} --> {2}", Name, oriOpState, currentOpState);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsWritten or Event.Error</returns>
|
||||
public Event Run()
|
||||
{
|
||||
var oriOpState = currentOpState;
|
||||
|
||||
if (currentOpState == OpState.GetUnitInfosRunning)
|
||||
{
|
||||
if (flexFlowCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return Event.InfoRead;
|
||||
}
|
||||
else if (!opCompleted)
|
||||
{
|
||||
log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
|
||||
opCompleted = true;
|
||||
if (GetUnitInfos(waterMeters) != Retv.OK)
|
||||
{
|
||||
anyError = true;
|
||||
}
|
||||
|
||||
var retval = anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
log.WarnFormat("{0} Run() returned {1}, op.state {2} --> {3}", Name, retval, oriOpState, currentOpState);
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
var retval = anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
log.WarnFormat("{0} Run() returned {1}, op.state {2} --> {3}", Name, retval, oriOpState, currentOpState);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
else if (currentOpState == OpState.SaveResultsRunning)
|
||||
{
|
||||
if (flexFlowCfg.DebugLevel == DebugMode.Simulate || batch.WaterMeters.Count == 0)
|
||||
{
|
||||
return Event.ResultsWritten;
|
||||
}
|
||||
else if (!opCompleted)
|
||||
{
|
||||
opCompleted = true;
|
||||
if (SaveResults(batch) != Retv.OK)
|
||||
{
|
||||
anyError = true;
|
||||
}
|
||||
var retval = anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
log.WarnFormat("{0} Run() returned {1}, op.state {2} --> {3}", Name, retval, oriOpState, currentOpState);
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
var retval = anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
log.WarnFormat("{0} Run() returned {1}, op.state {2} --> {3}", Name, retval, oriOpState, currentOpState);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.WarnFormat("{0} Run() returned {1}, op.state {2} --> {3}", Name, Event.None, oriOpState, currentOpState);
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
var oriOpState = currentOpState;
|
||||
currentOpState = OpState.None;
|
||||
log.WarnFormat("{0} Stop() completed, op.state {1} --> {2}", Name, oriOpState, currentOpState);
|
||||
}
|
||||
|
||||
|
||||
Retv GetUnitInfos(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
bool allOK = true;
|
||||
|
||||
foreach (var wm in waterMeters)
|
||||
{
|
||||
if (wm != null && !wm.Disabled)
|
||||
{
|
||||
GetOneUnitInfo(wm, (flexFlowCfg.GetUnitInfoApi == WebApi.REST));
|
||||
|
||||
if (wm.LastRecordIsNok)
|
||||
{
|
||||
allOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allOK ? Retv.OK : Retv.Error;
|
||||
}
|
||||
|
||||
|
||||
Retv GetOneUnitInfo(Results.Entities.WaterMeter wm, bool isRest)
|
||||
{
|
||||
string serviceName = isRest ? "GetUnitInfo REST" : "GetUnitInfo SOAP"; /// For logging only
|
||||
string url = flexFlowCfg.BaseUrl + flexFlowCfg.GetUnitInfoUrl; /// Complete URL from base URL and relative URL
|
||||
string localUserId = (!flexFlowCfg.SendUserId || string.IsNullOrEmpty(UserId)) ? "admin" : UserId;
|
||||
log.DebugFormat("{0} URL is {1}", serviceName, url);
|
||||
|
||||
if (string.IsNullOrEmpty(wm.SerialNr))
|
||||
{
|
||||
/// S/N is missing
|
||||
wm.LastRecordIsNok = false; /// OK, this is an RFID comm. error, not a production tracing error
|
||||
log.DebugFormat("{0} : pcbNr is missing", serviceName);
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
string request;
|
||||
if (isRest)
|
||||
{
|
||||
/// JSON request formatting
|
||||
request = string.Format("{{{0}\"StationName\": \"{1}\",{0}\"UserID\": \"{2}\",{0}\"SerialNumber\": \"{3}\",{0}}}",
|
||||
string.Empty, //Environment.NewLine,
|
||||
StationName,
|
||||
localUserId,
|
||||
wm.SerialNr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// TODO: Implement XML request formatting
|
||||
request = string.Format("{{{0}\"StationName\": \"{1}\",{0}\"UserID\": \"{2}\",{0}\"SerialNumber\": \"{3}\",{0}}}",
|
||||
string.Empty, //Environment.NewLine,
|
||||
StationName,
|
||||
localUserId,
|
||||
wm.SerialNr);
|
||||
}
|
||||
log.DebugFormat("{0} request (pcbNr = {1}):\r\n{2}", serviceName, wm.SerialNr, request);
|
||||
|
||||
/// Object to be updated when parsing the response
|
||||
UnitInfoData data = new UnitInfoData(wm.SerialNr, StationName, localUserId);
|
||||
|
||||
try
|
||||
{
|
||||
var webRequest = isRest ? CreateRestHttpWebRequest(url) : CreateSoapHttpWebRequest(url);
|
||||
|
||||
using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
|
||||
{
|
||||
streamWriter.Write(request);
|
||||
}
|
||||
|
||||
using (var streamReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
|
||||
{
|
||||
var response = streamReader.ReadToEnd();
|
||||
|
||||
log.DebugFormat("{0} response (pcbNr={1}):\r\n{2}", serviceName, wm.SerialNr, response);
|
||||
|
||||
if (isRest)
|
||||
{
|
||||
/// JSON response parsing
|
||||
string pattern = "\"id\":";
|
||||
int position = response.IndexOf(pattern) + pattern.Length;
|
||||
int length = response.Substring(position).IndexOfAny(new char[] { ',', '}', '\r', '\n' });
|
||||
int idummy;
|
||||
if (int.TryParse(response.Substring(position, length).Trim(), out idummy))
|
||||
{
|
||||
data.Id = idummy;
|
||||
}
|
||||
|
||||
pattern = "\"value\":";
|
||||
position = response.IndexOf(pattern) + pattern.Length;
|
||||
length = response.Substring(position).IndexOfAny(new char[] { ',', '}', '\r', '\n' });
|
||||
data.Value = response.Substring(position, length);
|
||||
|
||||
pattern = "\"ffUnitId\":";
|
||||
position = response.IndexOf(pattern) + pattern.Length;
|
||||
length = response.Substring(position).IndexOfAny(new char[] { ',', '}', '\r', '\n' });
|
||||
long ldummy;
|
||||
if (long.TryParse(response.Substring(position, length).Trim(), out ldummy))
|
||||
{
|
||||
data.FFUnitId = ldummy;
|
||||
}
|
||||
|
||||
pattern = "\"ffTestId\":";
|
||||
position = response.IndexOf(pattern) + pattern.Length;
|
||||
length = response.Substring(position).IndexOfAny(new char[] { ',', '}', '\r', '\n' });
|
||||
if (long.TryParse(response.Substring(position, length).Trim(), out ldummy))
|
||||
{
|
||||
data.FFTestId = ldummy;
|
||||
}
|
||||
|
||||
pattern = "\"ffPartId\":";
|
||||
position = response.IndexOf(pattern) + pattern.Length;
|
||||
length = response.Substring(position).IndexOfAny(new char[] { ',', '}', '\r', '\n' });
|
||||
if (long.TryParse(response.Substring(position, length).Trim(), out ldummy))
|
||||
{
|
||||
data.FFPartId = ldummy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
///
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("{0} failed: {1}", serviceName, exc.Message);
|
||||
}
|
||||
|
||||
return (data != null && data.Id == 0) ? Retv.OK : Retv.Error;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Write results of a batch of water meters to the DB
|
||||
/// </summary>
|
||||
/// <param name="batch">Batch entity</param>
|
||||
Retv SaveResults(Results.Entities.Batch batch)
|
||||
{
|
||||
try
|
||||
{
|
||||
int writtenRecordsCount = 0;
|
||||
foreach (var wMtr in batch.WaterMeters)
|
||||
{
|
||||
writtenRecordsCount += SaveOneUnitResult(wMtr, (flexFlowCfg.SaveResultsApi == WebApi.REST));
|
||||
}
|
||||
|
||||
log.ErrorFormat("Batch {0}: {1} of {2} watermeters written to the regular production tracing DB",
|
||||
batch.BatchNr, writtenRecordsCount, batch.WaterMeters.Count);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.WarnFormat("Failed to write results of batch {0} to production tracing DB: {1}",
|
||||
batch.BatchNr, exc.Message);
|
||||
return Retv.Error;
|
||||
}
|
||||
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Write one meter results to the DB
|
||||
/// </summary>
|
||||
/// <param name="wm">Watermeter entity</param>
|
||||
/// <returns>Number of written water meters (0 or 1)</returns>
|
||||
int SaveOneUnitResult(Results.Entities.WaterMeter wm, bool isRest)
|
||||
{
|
||||
string serviceName = isRest ? "SaveTestResult REST" : "SaveTestResult SOAP"; /// For logging only
|
||||
string url = flexFlowCfg.BaseUrl + flexFlowCfg.SaveResultsUrl; /// Complete URL from base URL and relative URL
|
||||
string localUserId = (!flexFlowCfg.SendUserId || string.IsNullOrEmpty(UserId)) ? "admin" : UserId;
|
||||
log.DebugFormat("{0} URL is {1}", serviceName, url);
|
||||
|
||||
if (string.IsNullOrEmpty(wm.SerialNr))
|
||||
{
|
||||
/// S/N is missing
|
||||
log.DebugFormat("{0} : pcbNr is missing", serviceName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Request formatting
|
||||
///
|
||||
string request;
|
||||
if (isRest)
|
||||
{
|
||||
/// JSON request formatting
|
||||
string status = wm.Passed ? "Passed" : "Failed";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine(string.Format("{{"));
|
||||
sb.AppendLine(string.Format(" \"timestamp\": \"{0:yyyy-MM-dd HH:mm:ss}\",", DateTime.Now));
|
||||
sb.AppendLine(string.Format(" \"syntaxRev\": \"1.1\","));
|
||||
sb.AppendLine(string.Format(" \"compatibleRev\": \"1.1\","));
|
||||
sb.AppendLine(string.Format(" \"factory\": {{"));
|
||||
sb.AppendLine(string.Format(" \"name\": \"{0}\",", "Flex Chennai"));
|
||||
sb.AppendLine(string.Format(" \"line\": \"\","));
|
||||
sb.AppendLine(string.Format(" \"tester\": \"{0}\",", StationName));
|
||||
sb.AppendLine(string.Format(" \"user\": \"{0}\"", localUserId));
|
||||
sb.AppendLine(string.Format(" }},"));
|
||||
sb.AppendLine(string.Format(" \"product\": {{"));
|
||||
sb.AppendLine(string.Format(" \"name\": \"{0}\",", "iPERL"));
|
||||
sb.AppendLine(string.Format(" \"revision\": \"{0}\"", "S4"));
|
||||
sb.AppendLine(string.Format(" }},"));
|
||||
sb.AppendLine(string.Format(" \"panel\": {{"));
|
||||
sb.AppendLine(string.Format(" \"id\": \"\","));
|
||||
sb.AppendLine(string.Format(" \"comment\": \"\","));
|
||||
sb.AppendLine(string.Format(" \"runmode\": \"{0}\",", "Production"));
|
||||
sb.AppendLine(string.Format(" \"timestamp\": \"{0:yyyy-MM-dd HH:mm:ss}\",", DateTime.Now));
|
||||
sb.AppendLine(string.Format(" \"testTime\": \"{0}\",", 0));
|
||||
sb.AppendLine(string.Format(" \"status\": \"{0}\",", status));
|
||||
sb.AppendLine(string.Format(" \"dut\": [{{"));
|
||||
sb.AppendLine(string.Format(" \"id\": \"{0}\",", wm.SerialNr));
|
||||
sb.AppendLine(string.Format(" \"comment\": \"\","));
|
||||
sb.AppendLine(string.Format(" \"panel\": \"{0}\",", 1));
|
||||
sb.AppendLine(string.Format(" \"socket\": \"{0}\",", 0));
|
||||
sb.AppendLine(string.Format(" \"timestamp\": \"{0:yyyy-MM-dd HH:mm:ss}\",", resultsTimeStamp));
|
||||
sb.AppendLine(string.Format(" \"runmode\": \"{0}\",", "Production"));
|
||||
sb.AppendLine(string.Format(" \"testTime\": \"{0}\",", (wm.Batch.EndTime - wm.Batch.StartTime).TotalSeconds.ToString("F0")));
|
||||
sb.AppendLine(string.Format(" \"status\": \"{0}\",", status));
|
||||
sb.AppendLine(string.Format(" \"group\": {{"));
|
||||
sb.AppendLine(string.Format(" \"name\": \"{0}\",", "iPERL"));
|
||||
sb.AppendLine(string.Format(" \"groupIndex\": \"{0}\",", 0));
|
||||
sb.AppendLine(string.Format(" \"loopIndex\": \"{0}\",", 0));
|
||||
sb.AppendLine(string.Format(" \"type\": \"{0}\",", "SequenceCall"));
|
||||
sb.AppendLine(string.Format(" \"moduleTime\": \"{0}\",", 0));
|
||||
sb.AppendLine(string.Format(" \"totalTime\": \"{0}\",", (wm.Batch.EndTime - wm.Batch.StartTime).TotalSeconds.ToString("F0")));
|
||||
sb.AppendLine(string.Format(" \"timestamp\": \"{0:yyyy-MM-dd HH:mm:ss}\",", resultsTimeStamp));
|
||||
sb.AppendLine(string.Format(" \"status\": \"{0}\"", status));
|
||||
sb.AppendLine(string.Format(" }}"));
|
||||
sb.AppendLine(string.Format(" }}]"));
|
||||
sb.AppendLine(string.Format(" }}"));
|
||||
sb.AppendLine(string.Format("}}"));
|
||||
request = sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
/// XML request formatting
|
||||
string status = wm.Passed ? "PASS" : "FAIL";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine(string.Format("<BATCH TIMESTAMP=\"{0}\" SYNTAX_REV=\"1.0\" COMPATIBLE_REV=\"1.0\">", resultsTimeStampStr));
|
||||
sb.AppendLine(string.Format(" <TIMESTAMP>{0}</TIMESTAMP>", resultsTimeStampStr));
|
||||
sb.AppendLine(string.Format(" <FACTORY NAME=\"\" LINE=\"\" TESTER=\"InitialATE(A)_03\" FIXTURE=\"YA134A451UM\" SHIFT=\"day\" USER=\"OP\"/>"));
|
||||
sb.AppendLine(string.Format(" <PRODUCT NAME=\"iPERL\" REVISION=\"S4\" FAMILY=\"\" CUSTOMER=\"HM\"/>"));
|
||||
sb.AppendLine(string.Format(" <PANEL ID=\"{0}\" COMMENT=\"\" RUNMODE=\"\" TIMESTAMP=\"{1}\" TESTTIME=\"16.6\" ENDTIME=\"{1}\" STATUS=\"{2}\">", wm.SerialNr, resultsTimeStampStr, status));
|
||||
sb.AppendLine(string.Format(" <DUT ID=\"{0}\" COMMENT=\"\" PANEL=\"0\" SOCKET=\"1\" TIMESTAMP=\"{1}\" TESTTIME=\"16.6\" ENDTIME=\"{1}\" STATUS=\"{2}\">", wm.SerialNr, resultsTimeStampStr, status));
|
||||
sb.AppendLine(string.Format(" <GROUP NAME=\"{0}\" STEPGROUP=\"Main\" GROUPINDEX=\"0\" LOOPINDEX=\"-1\" TYPE=\"\" RESOURCE=\"\" MODULETIME=\"\" TOTALTIME=\"\" TIMESTAMP=\"{1}\" STATUS=\"{2}\">", wm.SerialNr, resultsTimeStampStr, status));
|
||||
sb.AppendLine(string.Format(" <TEST NAME=\"Cavity\" DESCRIPTION=\"Cavity\" UNIT=\"\" VALUE=\"01\" HILIM=\"\" LOLIM=\"\" STATUS=\"{0}\" RULE=\"\" TARGET=\"\"/>", status));
|
||||
sb.AppendLine(string.Format(" </GROUP>"));
|
||||
sb.AppendLine(string.Format(" </DUT>"));
|
||||
sb.AppendLine(string.Format(" </PANEL>"));
|
||||
sb.AppendLine(string.Format("</BATCH>"));
|
||||
request = sb.ToString();
|
||||
}
|
||||
log.DebugFormat("{0} request (pcbNr = {1}):\r\n{2}", serviceName, wm.SerialNr, request);
|
||||
|
||||
/// Object to be updated when parsing the response
|
||||
ResultsData data = new ResultsData(wm.SerialNr, StationName, localUserId);
|
||||
|
||||
try
|
||||
{
|
||||
var webRequest = isRest ? CreateRestHttpWebRequest(url) : CreateSoapHttpWebRequest(url);
|
||||
|
||||
using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
|
||||
{
|
||||
streamWriter.Write(request);
|
||||
}
|
||||
|
||||
using (var streamReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
|
||||
{
|
||||
var response = streamReader.ReadToEnd();
|
||||
|
||||
log.DebugFormat("{0} response (pcbNr={1}):\r\n{2}", serviceName, wm.SerialNr, response);
|
||||
|
||||
if (isRest)
|
||||
{
|
||||
/// JSON response parsing
|
||||
string pattern = "\"id\":";
|
||||
int position = response.IndexOf(pattern) + pattern.Length;
|
||||
int length = response.Substring(position).IndexOfAny(new char[] { ',', '}', '\r', '\n' });
|
||||
int idummy;
|
||||
if (int.TryParse(response.Substring(position, length).Trim(), out idummy))
|
||||
{
|
||||
data.Id = idummy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/// TODO: XML resonse parsing
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("{0} failed: {1}", serviceName, exc.Message);
|
||||
}
|
||||
|
||||
return (data != null && data.Id == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
public HttpWebRequest CreateRestHttpWebRequest(string url)
|
||||
{
|
||||
var request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.ContentType = "application/json";
|
||||
request.Method = "POST";
|
||||
return request;
|
||||
}
|
||||
|
||||
public HttpWebRequest CreateSoapHttpWebRequest(string url)
|
||||
{
|
||||
var request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.Headers.Add(@"SOAPAction:http://tempuri.org/Addition");
|
||||
request.ContentType = "application/xml";
|
||||
request.Accept = "text/xml";
|
||||
request.Method = "POST";
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
198
TBF/BenchControl/Output/FlexFlow/FlexFlowCfg.cs
Normal file
198
TBF/BenchControl/Output/FlexFlow/FlexFlowCfg.cs
Normal file
@ -0,0 +1,198 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Config.Entities;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow
|
||||
{
|
||||
public enum WebApi
|
||||
{
|
||||
REST,
|
||||
SOAP,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds FlexFlow.Rest configuration.
|
||||
/// </summary>
|
||||
public class FlexFlowCfg : ComponentCfgBase, Generic.IComponentCfg, IParamsProvider
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlexFlowCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public string BaseUrl;
|
||||
public WebApi GetUnitInfoApi;
|
||||
public string GetUnitInfoUrl;
|
||||
public WebApi SaveResultsApi;
|
||||
public string SaveResultsUrl;
|
||||
public bool CheckPreviousRecords;
|
||||
public bool SaveResults;
|
||||
public bool SendUserId;
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
FlexFlowCfg() { }
|
||||
|
||||
public FlexFlowCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = string.Empty;
|
||||
InitializeAll();
|
||||
}
|
||||
|
||||
public string ComponentName { get { return Name; } }
|
||||
|
||||
public void InitializeAll()
|
||||
{
|
||||
BaseUrl = "http://gdlm02205:4450/?wsdl";
|
||||
GetUnitInfoUrl = string.Empty;
|
||||
SaveResultsUrl = string.Empty;
|
||||
CheckPreviousRecords = true;
|
||||
SaveResults = true;
|
||||
SendUserId = true;
|
||||
}
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
"Base URL", /// 0
|
||||
"Get unit info", /// 1
|
||||
"GetUnitInfo Web API", /// 2
|
||||
"GetUnitInfo URL relative to base URL", /// 3
|
||||
"Save result", /// 4
|
||||
"SaveResult Web API", /// 5
|
||||
"SaveResult URL relative to base URL", /// 6
|
||||
"Send user ID", /// 7
|
||||
};
|
||||
public string ParamName(int i) { return paramNames[i]; }
|
||||
public int ParamsCount() { return paramNames.Length; }
|
||||
|
||||
public ICollection<string> ParamValues(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 7:
|
||||
return new string[] { Strings.yes, Strings.no };
|
||||
case 2:
|
||||
case 5:
|
||||
return new string[] { WebApi.REST.ToString(), WebApi.SOAP.ToString() };
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: return BaseUrl;
|
||||
case 1: return CheckPreviousRecords ? Strings.yes : Strings.no;
|
||||
case 2: return GetUnitInfoApi.ToString();
|
||||
case 3: return GetUnitInfoUrl;
|
||||
case 4: return SaveResults ? Strings.yes : Strings.no;
|
||||
case 5: return SaveResultsApi.ToString();
|
||||
case 6: return SaveResultsUrl;
|
||||
case 7: return SendUserId ? Strings.yes : Strings.no;
|
||||
default:
|
||||
return string.Format("{0} CheckPrev.={1}, SaveResults={2}, URL={3}, URL2={4}",
|
||||
Name,
|
||||
CheckPreviousRecords,
|
||||
SaveResults,
|
||||
BaseUrl,
|
||||
GetUnitInfoUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string str)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: BaseUrl = str; return CfgUpdateFlags.RestartRqrd;
|
||||
case 1: CheckPreviousRecords = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd;
|
||||
case 2:
|
||||
foreach (var wa in new WebApi[] { WebApi.REST, WebApi.SOAP })
|
||||
if (str == wa.ToString())
|
||||
{
|
||||
GetUnitInfoApi = wa;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
return CfgUpdateFlags.None;
|
||||
case 3: GetUnitInfoUrl = str; return CfgUpdateFlags.RestartRqrd;
|
||||
case 4: SaveResults = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd;
|
||||
case 5:
|
||||
foreach (var wa in new WebApi[] { WebApi.REST, WebApi.SOAP })
|
||||
if (str == wa.ToString())
|
||||
{
|
||||
SaveResultsApi = wa;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
return CfgUpdateFlags.None;
|
||||
case 6: SaveResultsUrl = str; return CfgUpdateFlags.RestartRqrd;
|
||||
case 7: SendUserId = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 3:
|
||||
case 6:
|
||||
return true;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
case 7:
|
||||
if (ParamValues(i).Contains(strValue)) return true;
|
||||
break;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = ParamName(i) + " is invalid";
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(FlexFlowCfg prms)
|
||||
{
|
||||
prms.BaseUrl = this.BaseUrl;
|
||||
prms.CheckPreviousRecords = this.CheckPreviousRecords;
|
||||
prms.GetUnitInfoApi = this.GetUnitInfoApi;
|
||||
prms.GetUnitInfoUrl = this.GetUnitInfoUrl;
|
||||
prms.SaveResults = this.SaveResults;
|
||||
prms.SaveResultsApi = this.SaveResultsApi;
|
||||
prms.SaveResultsUrl = this.SaveResultsUrl;
|
||||
prms.SendUserId = this.SendUserId;
|
||||
}
|
||||
|
||||
public Config.Entities.IParamsProvider Clone()
|
||||
{
|
||||
FlexFlowCfg pars = new FlexFlowCfg();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public bool UpdateEmbeddedDbEntity()
|
||||
{
|
||||
return true; /// =OK, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,323 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using Config.Entities;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow.Rest
|
||||
{
|
||||
public class FlexFlow : ComponentBase, IOperation, GenericDevices.IResultsWriter, GenericDevices.IStartInfoReader, Generic.IDevice
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(FlexFlow));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
FlexFlowCfg flexFlowCfg;
|
||||
|
||||
public string StationName
|
||||
{
|
||||
get
|
||||
{
|
||||
var benchInfo = TBF.BenchControl.Sequences.ProcessData.BenchInfo;
|
||||
return (benchInfo != null) ? benchInfo.TestBenchName : "TestBench";
|
||||
}
|
||||
}
|
||||
|
||||
public string UserID { get { return Users.GlobalData.GetCurrentUserName(); } }
|
||||
|
||||
|
||||
enum Retv
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
}
|
||||
|
||||
enum OpState
|
||||
{
|
||||
None,
|
||||
GetUnitInfosScheduled,
|
||||
GetUnitInfosRunning,
|
||||
SaveResultsScheduled,
|
||||
SaveResultsRunning,
|
||||
}
|
||||
///
|
||||
OpState currentOpState;
|
||||
bool opCompleted;
|
||||
bool anyError;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Watermeters to check at the beginning of the cycle
|
||||
/// </summary>
|
||||
IList<Results.Entities.WaterMeter> waterMeters;
|
||||
|
||||
/// <summary>
|
||||
/// Data (tracing records) to write at the end of cycle
|
||||
/// </summary>
|
||||
Results.Entities.Batch batch;
|
||||
|
||||
|
||||
public FlexFlow() {}
|
||||
|
||||
public FlexFlow(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
flexFlowCfg = cfg as FlexFlowCfg;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
currentOpState = OpState.None;
|
||||
|
||||
if (flexFlowCfg.DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
/// TODO: Initialize FlexFlow
|
||||
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.FatalFormat("{0} simulated: {1}", Name, this);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// IDevice interface implementation
|
||||
///
|
||||
public void RunDeviceBefore() { }
|
||||
public void RunDeviceAfter() { }
|
||||
///
|
||||
public void StopDevice()
|
||||
{
|
||||
if (flexFlowCfg.DebugLevel != DebugMode.Normal) return;
|
||||
|
||||
/// TODO: Close FlexFlow
|
||||
}
|
||||
public void StopDevice2() {}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads information on start of a cycle, Events: Event.InfoRead
|
||||
/// </summary>
|
||||
/// <param name="waterMeters">Results of water meters</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ReadStartInfoOp(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
if (!flexFlowCfg.CheckPreviousRecords)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.GetUnitInfosRunning) || (currentOpState == OpState.SaveResultsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.waterMeters = waterMeters;
|
||||
currentOpState = OpState.GetUnitInfosScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the test cycle results into a file, Events: Event.ResultsWritten
|
||||
/// </summary>
|
||||
/// <param name="procedure">Procedure to print the results of</param>
|
||||
/// <param name="unsortedResults">Results to write into the file</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ProcessResultsOp(Results.Entities.Batch batch)
|
||||
{
|
||||
if (!flexFlowCfg.SaveResults)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.GetUnitInfosRunning) || (currentOpState == OpState.SaveResultsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.batch = batch;
|
||||
currentOpState = OpState.SaveResultsScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
if (currentOpState == OpState.GetUnitInfosScheduled)
|
||||
{
|
||||
currentOpState = OpState.GetUnitInfosRunning;
|
||||
}
|
||||
else if (currentOpState == OpState.SaveResultsScheduled)
|
||||
{
|
||||
currentOpState = OpState.SaveResultsRunning;
|
||||
}
|
||||
|
||||
opCompleted = false;
|
||||
anyError = false;
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsWritten or Event.Error</returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (currentOpState == OpState.GetUnitInfosRunning)
|
||||
{
|
||||
if (flexFlowCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return Event.InfoRead;
|
||||
}
|
||||
else if (!opCompleted)
|
||||
{
|
||||
log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
|
||||
opCompleted = true;
|
||||
if (GetUnitInfos(waterMeters) != Retv.OK)
|
||||
{
|
||||
anyError = true;
|
||||
}
|
||||
return anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
}
|
||||
}
|
||||
else if (currentOpState == OpState.SaveResultsRunning)
|
||||
{
|
||||
if (flexFlowCfg.DebugLevel == DebugMode.Simulate || batch.WaterMeters.Count == 0)
|
||||
{
|
||||
return Event.ResultsWritten;
|
||||
}
|
||||
else if (!opCompleted)
|
||||
{
|
||||
log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
|
||||
opCompleted = true;
|
||||
if (SaveResults(batch) != Retv.OK)
|
||||
{
|
||||
anyError = true;
|
||||
}
|
||||
return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
}
|
||||
else
|
||||
{
|
||||
return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Event.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
currentOpState = OpState.None;
|
||||
}
|
||||
|
||||
|
||||
Retv GetUnitInfos(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
bool allOK = true;
|
||||
|
||||
foreach (var wm in waterMeters)
|
||||
{
|
||||
if (wm != null && !wm.Disabled)
|
||||
{
|
||||
GetOneUnitInfo(wm);
|
||||
if (wm.LastRecordIsNok)
|
||||
{
|
||||
allOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allOK ? Retv.OK : Retv.Error;
|
||||
}
|
||||
|
||||
Retv GetOneUnitInfo(Results.Entities.WaterMeter wm)
|
||||
{
|
||||
if (string.IsNullOrEmpty(wm.SerialNr))
|
||||
{
|
||||
/// S/N is missing
|
||||
wm.LastRecordIsNok = false; /// OK, this is an RFID comm. error, not a production tracing error
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
string request;
|
||||
if (flexFlowCfg.DoNotSendUserId || string.IsNullOrEmpty(UserID))
|
||||
{
|
||||
request = '{'
|
||||
+ string.Format("{0}\"serialNumber\": \"{1}\",{0}\"stationName\": \"{2}\"{0}",
|
||||
Environment.NewLine, wm.SerialNr, StationName)
|
||||
+ '}';
|
||||
}
|
||||
else
|
||||
{
|
||||
request = '{'
|
||||
+ string.Format("{0}\"serialNumber\": \"{1}\",{0}\"stationName\": \"{2}\",{0}\"userId\": \"{3}\"{0}",
|
||||
Environment.NewLine, wm.SerialNr, StationName, UserID)
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/// TODO: Invoke GetUnitInfo
|
||||
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Write results of a batch of water meters to the DB
|
||||
/// </summary>
|
||||
/// <param name="batch">Batch entity</param>
|
||||
Retv SaveResults(Results.Entities.Batch batch)
|
||||
{
|
||||
try
|
||||
{
|
||||
int writtenRecordsCount = 0;
|
||||
foreach (var wMtr in batch.WaterMeters)
|
||||
{
|
||||
if (wMtr.SessionId == 1)
|
||||
{
|
||||
writtenRecordsCount += SaveOneUnitResult(wMtr);
|
||||
}
|
||||
}
|
||||
|
||||
log.ErrorFormat("Batch {0}: {1} of {2} watermeters written to the regular production tracing DB",
|
||||
batch.BatchNr, writtenRecordsCount, batch.WaterMeters.Count);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.WarnFormat("Failed to write results of batch {0} to production tracing DB: {1}",
|
||||
batch.BatchNr, exc.Message);
|
||||
return Retv.Error;
|
||||
}
|
||||
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Write one meter results to the DB
|
||||
/// </summary>
|
||||
/// <param name="wm">Watermeter entity</param>
|
||||
/// <returns>Number of written water meters (0 or 1)</returns>
|
||||
int SaveOneUnitResult(Results.Entities.WaterMeter wm)
|
||||
{
|
||||
if (string.IsNullOrEmpty(wm.SerialNr) || (wm.ProcessId == 0))
|
||||
{
|
||||
/// Without PCB number there is no DB activity
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// TODO: Invoke SaveResult
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,172 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2021 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Config.Entities;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.Resources;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow.Rest
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds FlexFlow.Rest configuration.
|
||||
/// </summary>
|
||||
public class FlexFlowCfg : ComponentCfgBase, Generic.IComponentCfg, IParamsProvider
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(FlexFlowCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public string Url;
|
||||
public string Url2;
|
||||
public bool CheckPreviousRecords;
|
||||
public bool SaveResults;
|
||||
public bool DoNotSendUserId;
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
FlexFlowCfg() { }
|
||||
|
||||
public FlexFlowCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = string.Empty;
|
||||
InitializeAll();
|
||||
}
|
||||
|
||||
public string ComponentName { get { return Name; } }
|
||||
|
||||
public void InitializeAll()
|
||||
{
|
||||
Url = "http://gdlm02205:4450/?wsdl";
|
||||
Url2 = string.Empty;
|
||||
CheckPreviousRecords = true;
|
||||
SaveResults = true;
|
||||
DoNotSendUserId = true;
|
||||
}
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
"URL",
|
||||
"URL2",
|
||||
"Get Unit Info",
|
||||
"Save Result",
|
||||
"Do not send UserId",
|
||||
};
|
||||
public string ParamName(int i) { return paramNames[i]; }
|
||||
public int ParamsCount() { return paramNames.Length; }
|
||||
|
||||
public ICollection<string> ParamValues(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return new List<string>() { Strings.yes, Strings.no };
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return Url;
|
||||
case 1:
|
||||
return Url2;
|
||||
case 2:
|
||||
return CheckPreviousRecords ? Strings.yes : Strings.no;
|
||||
case 3:
|
||||
return SaveResults ? Strings.yes : Strings.no;
|
||||
case 4:
|
||||
return DoNotSendUserId ? Strings.yes : Strings.no;
|
||||
default:
|
||||
return string.Format("{0} CheckPrev.={1}, SaveResults={2}, URL={3}, URL2={4}",
|
||||
Name,
|
||||
CheckPreviousRecords,
|
||||
SaveResults,
|
||||
Url,
|
||||
Url2);
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
Url = strValue;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 1:
|
||||
Url2 = strValue;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 2:
|
||||
CheckPreviousRecords = (strValue == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 3:
|
||||
SaveResults = (strValue == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
case 4:
|
||||
DoNotSendUserId = (strValue == Strings.yes);
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
default:
|
||||
return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return true;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if (ParamValues(i).Contains(strValue)) return true;
|
||||
break;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = ParamName(i) + " is invalid";
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(FlexFlowCfg prms)
|
||||
{
|
||||
prms.Url = this.Url;
|
||||
prms.Url2 = this.Url2;
|
||||
prms.CheckPreviousRecords = this.CheckPreviousRecords;
|
||||
prms.SaveResults = this.SaveResults;
|
||||
prms.DoNotSendUserId = this.DoNotSendUserId;
|
||||
}
|
||||
|
||||
public Config.Entities.IParamsProvider Clone()
|
||||
{
|
||||
FlexFlowCfg pars = new FlexFlowCfg();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public bool UpdateEmbeddedDbEntity()
|
||||
{
|
||||
return true; /// =OK, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
22
TBF/BenchControl/Output/FlexFlow/ResultsData.cs
Normal file
22
TBF/BenchControl/Output/FlexFlow/ResultsData.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow
|
||||
{
|
||||
public class ResultsData
|
||||
{
|
||||
public string SerialNr;
|
||||
public string StationName;
|
||||
public string UserId;
|
||||
|
||||
public int Id;
|
||||
|
||||
public ResultsData(string serialNr, string stationName, string userId)
|
||||
{
|
||||
SerialNr = serialNr;
|
||||
StationName = stationName;
|
||||
UserId = userId;
|
||||
|
||||
Id = 9999;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
TBF/BenchControl/Output/FlexFlow/UnitInfoData.cs
Normal file
27
TBF/BenchControl/Output/FlexFlow/UnitInfoData.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.BenchControl.Output.FlexFlow
|
||||
{
|
||||
public class UnitInfoData
|
||||
{
|
||||
public string SerialNr;
|
||||
public string StationName;
|
||||
public string UserId;
|
||||
|
||||
public int Id;
|
||||
public string Value;
|
||||
public long FFUnitId;
|
||||
public long FFTestId;
|
||||
public long FFPartId;
|
||||
|
||||
public UnitInfoData(string serialNr, string stationName, string userId)
|
||||
{
|
||||
SerialNr = serialNr;
|
||||
StationName = stationName;
|
||||
UserId = userId;
|
||||
|
||||
Id = 9999;
|
||||
Value = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1599,7 +1599,7 @@ namespace TBF.BenchControl.Sequences
|
||||
|
||||
for (int i = 0; i < BatchRslts.WMPositionsCount; i++)
|
||||
{
|
||||
float errorPct = 0;
|
||||
double errorPct = Convert.ToDouble((i % 10) - 5) / 2.0;
|
||||
|
||||
Results.Entities.MeterTestRslt meterRslt = ProcessData.BatchRslts.GetMeterTestRslt(fullTestName, i, CompoundMeterId.Single);
|
||||
IRegReader regReader = sensPath.RegisterReaders[i];
|
||||
@ -1618,7 +1618,7 @@ namespace TBF.BenchControl.Sequences
|
||||
meterRslt.TimestampEnd = tstRslt.TargetTime();
|
||||
meterRslt.TestTime = tstRslt.TargetTime();
|
||||
meterRslt.Error = errorPct;
|
||||
meterRslt.Passed = true;
|
||||
meterRslt.Passed = errorPct >= test.ErrLimLo + test.Uncertainty && errorPct <= test.ErrLimHi - test.Uncertainty;
|
||||
meterRslt.TestDone = true;
|
||||
tstRslt.TestDone = true;
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ namespace TBF.BenchControl
|
||||
Factories.Add(new Output.FileWriters.Xml.FactoryCompound());
|
||||
Factories.Add(new Output.FileWriters.Xml.FactoryHeatMeters());
|
||||
Factories.Add(new Output.FileWriters.XmlBatch.FactorySingle());
|
||||
Factories.Add(new Output.FlexFlow.Rest.Factory());
|
||||
Factories.Add(new Output.FlexFlow.Factory());
|
||||
Factories.Add(new Output.Printers.Enhanced.FactorySingle());
|
||||
Factories.Add(new Output.Printers.Enhanced.FactoryCompound());
|
||||
Factories.Add(new Output.Printers.Enhanced.FactoryHeatMeters());
|
||||
|
||||
@ -141,6 +141,7 @@
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Web" />
|
||||
@ -1107,9 +1108,11 @@
|
||||
<Compile Include="BenchControl\Output\FileWriters\Xml\WriterCfgCtrl.designer.cs">
|
||||
<DependentUpon>WriterCfgCtrl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\Output\FlexFlow\Rest\Factory.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\Rest\FlexFlow.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\Rest\FlexFlowCfg.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\Factory.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\FlexFlow.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\FlexFlowCfg.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\ResultsData.cs" />
|
||||
<Compile Include="BenchControl\Output\FlexFlow\UnitInfoData.cs" />
|
||||
<Compile Include="BenchControl\Output\HeaderFooterDlg.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user