AOI_Saki_SaveProcessData.cs
*AOI_Saki_SaveProcessData.cs*
using Bartech.SGCore.Base;
using Bartech.SGCore.Helpers;
using Bartech.SGCore.Local;
using Bartech.SGCore.Local.Services;
using Bartech.SGCore.Logic.NVCZ.Modules.AOI.Model;
using Bartech.SGCore.Logic.NVCZ.Modules.LaserParser.Model;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.Xpo.Metadata;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using xTrace03_SG_Data;
using PartDataStatus = Bartech.SGCore.Local.DataObjects.PartDataStatus;
using xdata = xTrace03_SG_Data;
namespace Bartech.SGCore.Logic.NVCZ.Modules.AOI
{
[XModule("NVCZ_AOI_Saki_SaveData", "Modul pro ukladani procesnich dat z AOI Saki", ModuleGroupType.External, applicationType: xTraceApplicationType.NvCzAOI)]
public class AOI_Saki_SaveProcessData : SGModuleLocal
{
#region Constructor
public AOI_Saki_SaveProcessData(SGSession session, MSSQL cData)
: base(session)
{
m_cData = cData;
Session.Initialized += new EventHandler((s, e) =>
{
InitXPO(m_cData);
m_dxSession = Session.Resolve<SGDxSessionLocker>();
});
m_aoiSakiSvc = Session.Resolve<AoiSakiService>();
}
#endregion
#region Private variables
private AoiSakiService m_aoiSakiSvc;
private MSSQL m_cData;
private IDataLayer m_cDataDL;
private SGDxSessionLocker m_dxSession;
private string m_divrgCode = "F00001";
private SGDivergenceItem m_divrg;
private int m_resizedImagePercents = 80;
private string m_csvFilePath = string.Empty;
private string m_csvOriginalFilePath = string.Empty;
private string m_TestOK = "Ok";
private string m_addToImageName = "_Color";
private string m_ngTestFilePath = string.Empty;
private bool m_changed = false;
private string m_panelPhotoFileName = "CURRENTA.jpg";
private int m_aoiNgGSStatus = 35;
private SavePanelImage m_savePanelImage = SavePanelImage.Error;
private int m_addToCsvFileNameInterval = 3;
private bool m_sendDPMOAlarm = true;
private int m_boundDPMO = 0;
private string m_DPMOKatalogParam = string.Empty;
private string m_DPMOAlarmCode = "A20043";
private bool m_sendFalseErrorAlarm = true;
private int m_boundFalseError = 0;
private string m_falseErrorKatalogParam = string.Empty;
private string m_falseErrorAlarmCode = "A20042";
private int falseErrorCheckInterval = 15;
private AOIAlarmVariables alarmVariablesFalseErrors;
private AOIAlarmVariables alarmVariablesDPMO;
private Dictionary<long, AOIGUIHelp> subBoardNotes = new Dictionary<long, AOIGUIHelp>();
private bool m_showMatrix = true;
private string m_correctBarcode = string.Empty;
private bool m_useCsvFileForOpportunities = false;
#endregion
#region Constants
private const string PASS = "PASS";
private const string FAIL = "FAIL";
private const string OK = "Ok";
#endregion
#region Module overrides
protected override bool OnSetParameters()
{
m_divrgCode = Session.SysParams.TryGetString(this, "DivrgBarcode", m_divrgCode, "Barkód chyby, která se zapíše v případě chyby.");
m_ngTestFilePath = Session.SysParams.TryGetString(this, "FilePathNgTest", m_ngTestFilePath, "Cesta ke složkám se zákazníky ve kterých se nacházejí výsledky testů panelů u kterých něco rozhodoval operátor.");
m_sendDPMOAlarm = Session.SysParams.GetBoolean(this, "SendDPMOAlarm", m_sendDPMOAlarm, "Jestli sa má odeslat alarm, kvůli KPI DPMO.");
m_boundDPMO = Session.SysParams.GetParamValue<int>(this, "DPMOLimit", m_boundDPMO, "Nastavení limitu pro poslání alarmu z důvodu KPI DPMO. Pokud je hodnota 0, pak se bere hodnota z katalogového parametru určeného hodnotou DPMOKatalogParam.");
m_DPMOKatalogParam = Session.SysParams.TryGetString(this, "DPMOKatalogParam", m_DPMOKatalogParam, "Katalogový parametr ze kterého se získá hodnota meze pro KPI DPMO.");
m_DPMOAlarmCode = Session.SysParams.TryGetString(this, "DPMOAlarmCode", m_DPMOAlarmCode, "Kód alarmu, který se vyvolá při překročení meze DPMO.");
m_sendFalseErrorAlarm = Session.SysParams.GetBoolean(this, "SendFalseErrorAlarm", m_sendFalseErrorAlarm, "Jestli se má odeslat alarm, pokud počet falešných chyb překročí určitou mez.");
m_boundFalseError = Session.SysParams.GetParamValue<int>(this, "FalseErrorLimit", m_boundFalseError, "Nastavení limitu pro poslání alarmu z důvodu falešných chyb. Pokud je hodnota 0, pak se bere hodnota z katalogového parametru určeného hodnotou FalseErrorKatalogParam.");
m_falseErrorKatalogParam = Session.SysParams.TryGetString(this, "FalseErrorKatalogParam", m_falseErrorKatalogParam, "Katalogový parametr ze kterého se získá hodnota meze pro falešné chyby.");
m_falseErrorAlarmCode = Session.SysParams.TryGetString(this, "FalseErrorAlarmCode", m_falseErrorAlarmCode, "Kód alarmu, který se vyvolá při překročení meze počtu falešných chyb.");
falseErrorCheckInterval = Session.SysParams.GetParamValue<int>(this, "AlarmInterval", falseErrorCheckInterval, "Nastavení v minutách po jaké době se mají posílat alarmy.");
m_resizedImagePercents = Session.SysParams.GetInt32(this, "ResizedImagePercents", m_resizedImagePercents, "Hodnota udávající na kolik procent původního obrázku se má zmenšit komprimovaný obrázek.");
m_csvFilePath = Session.SysParams.TryGetString(this, "FilePathCSV", m_csvFilePath, "Cesta k adresářům, jejichž název je ve formátu yyyy-mm, ve kterých se nacházejí csv soubory.");
m_panelPhotoFileName = Session.SysParams.TryGetString(this, "PanelPhotoFileName", m_panelPhotoFileName, "Jméno souboru s příponou, jenž obsahuje fotku celého panelu.");
m_aoiNgGSStatus = Session.SysParams.GetInt32(this, "AoiNgGSStatus", m_aoiNgGSStatus, "Hodnota udávající jaký status se nastaví dílu při NOT OK testu dílu na pracovišti.");
m_savePanelImage = Session.SysParams.GetEnum(this, "SavePanelImage", m_savePanelImage, "Kdy ukládat fotku panelu. Hodnoty: Error - pouze pokud panel obsahuje opravdouvou chybu, FalseError - pokud panel obsahuje jakoukoliv chybu, NotSave - neukládat obrázek nikdy.");
m_showMatrix = Session.SysParams.GetBoolean(this, "ShowMatrix", m_showMatrix, "Zobrazovat matici s OK/NOK PCB?");
m_addToImageName = Session.SysParams.TryGetString(this, "AddToImageName", m_addToImageName, "Řetězec, který se vloží na konec názvu souboru s obrázkem chyby.");
m_csvOriginalFilePath = Session.SysParams.TryGetString(this, "FilePathCsvOriginal", m_csvOriginalFilePath, "Cesta k adresáři do kterého AOI generuje soubory typu csv.");
m_addToCsvFileNameInterval = Session.SysParams.GetInt32(this, "CsvTimeFileInterval", m_addToCsvFileNameInterval, "Hodnota udávající kolik vteřin bude postupně přičtěno/odečteno od časové hodnoty v bfre souboru v případě, že nebude nalezen soubor s originální hodnotou.");
m_useCsvFileForOpportunities = Session.SysParams.GetBoolean(this, "UseCsvFileForOpportunities", m_useCsvFileForOpportunities, "Parametr rozhodující o tom zda se při pokusu o získání počtu opportunities na rozhodovacím terminálu použije hledání csv souboru.");
if (Session.ProcessContext.SakiTypeOfWorkPlace == TypeOfWorkPlace.DecisionTerminal) // pokud jsme na rozhodovacím pracovišti, tak musí existovat složky s výsledky, je to schválně ve dvou if-kách, aby bylo poznat která složka neexistuje
{
if (Directory.Exists(m_ngTestFilePath) == false)
{
Message = Log(LogMsg.FILEGUARD_DirectoryNotFound, m_ngTestFilePath);
return false;
}
if (Directory.Exists(m_csvFilePath) == false)
{
Message = Log(LogMsg.FILEGUARD_DirectoryNotFound, m_csvFilePath);
return false;
}
if (m_addToCsvFileNameInterval < 0)
{
Message = Log(LogMsg.WORKPLACEPARAMETER_NotCorrectFormat, "CsvTimeFileInterval", "NVCZ AOI Saki SaveData");
return false;
}
Session.ReworkLists.LoadDivergencesAll();
var list = Session.ReworkLists.DivergencesAll.Where(p => p.Key == m_divrgCode);
try { m_divrg = list.First().Value; } catch (Exception ex) { throw new Exception("Unknown Divrg barcode", ex); }
}
if (!string.IsNullOrEmpty(m_ngTestFilePath))
{
Session.ProcessContext.SakiNgFilePath = m_ngTestFilePath;
}
return base.OnSetParameters();
}
public override SGLMState ModuleChecker(SGTreeModuleData mdata)
{
if (Session.ProcessContext.SakiTypeOfWorkPlace == TypeOfWorkPlace.Machine)
{
if (Session.ProcessContext.SakiData.IsBypassMode == true)
{
Session.WorkPlaceSetting.InfoData.LastPartBarcode = Session.ProcessContext.SakiData.ManageCode;
return SGLMState.Handled | SGLMState.OK | SGLMState.UpLevel;
}
}
return base.ModuleChecker(mdata);
}
public override SGLMState HandlePortData(SGTreeModuleData mdata, SGReceivedData data)
{
SGLMState s = SGLMState.NotHandled;
if (mdata.LevelState == SGLevelState.Echo)
{
if (Session.Part.DoPart.IsPartStarted)
{
switch (Session.ProcessContext.SakiTypeOfWorkPlace)
{
case TypeOfWorkPlace.Machine:
s = AOICheckWorkplace();
break;
case TypeOfWorkPlace.DecisionTerminal:
s = AOIDeciderWorkplace(Session.Part.DoPart.CurBarcode);
break;
default:
break;
}
}
else
{
Log(LogMsg.CUSTOM_WARNING_MSG, $"NEPOVOLENÁ AKCE: Není nastartovaný díl. Modul NVCZ AOI SAKI SAVEDATA, Echo, typ pracoviště={Session.ProcessContext.SakiTypeOfWorkPlace.ToString()}");
s = SGLMState.Handled | SGLMState.Fail | SGLMState.ResetLevel;
}
}
else if (mdata.LevelState == SGLevelState.WaitingForData)
{
Log(LogMsg.CUSTOM_WARNING_MSG, $"NEPOVOLENÁ AKCE: Není nastartovaný díl. Modul NVCZ AOI SAKI SAVEDATA, WaitingForData, typ pracoviště={Session.ProcessContext.SakiTypeOfWorkPlace.ToString()}");
s = SGLMState.Handled | SGLMState.Fail | SGLMState.ResetLevel;
}
return s;
}
#endregion
#region Helper functions
private SGLMState AOIDeciderWorkplace(string startedBarcode)
{
SGLMState s = SGLMState.NotHandled;
if (Session.ProcessContext.AOI_Data.IsJobChanged == true)
{
Session.ProcessContext.AOI_Data.IsJobChanged = false;
InitializeAlarms();
}
Tuple<string, bool> barcode = new Tuple<string, bool>(startedBarcode, false);
string bcd = string.Empty;
string barcodeWithoutSpecialCharacter = string.Empty;
if (Session.ProcessContext.EscapeHelper.IsSerialNumberNormalized(startedBarcode, ref bcd))
{
barcode = new Tuple<string, bool>(bcd, true);
}
string tempPathToFolder = Path.Combine(m_ngTestFilePath, Session.ProcessContext.SakiCustomer, Session.ProcessContext.SakiProgramName, "Lot");
if (Directory.Exists(tempPathToFolder) == false)
{
Message = Log(LogMsg.AOISAKI_DirectoryWithResultDoesNotExists, tempPathToFolder);
return SGLMState.Handled | SGLMState.Fail | SGLMState.ResetLevel;
}
Log(LogMsg.CUSTOM_INFO_MSG, $"Hledám všechny složky na cestě: {tempPathToFolder}");
List<string> directories = Directory.GetDirectories(tempPathToFolder).ToList();
StringBuilder sb = new StringBuilder();
foreach (var item in directories)
{
sb.Append(Path.GetFileName(item));
sb.Append(", ");
}
Log(LogMsg.CUSTOM_INFO_MSG, $"Seznam všech složek v adresáři {tempPathToFolder}: {sb.ToString()}");
sb.Clear();
List<string> directoriesWithBarcode = new List<string>();
DateTime lastWriteTime = DateTime.MinValue;
int indexOfDirectory = 0;
Log(LogMsg.CUSTOM_INFO_MSG, $"Hledám složku jejíž název obsahuje {barcode.Item1} ");
foreach (string path in directories)
{
if (path.Contains(barcode.Item1))
{
directoriesWithBarcode.Add(path);
}
}
if (directoriesWithBarcode.Count() == 0)
{
Log(LogMsg.CUSTOM_INFO_MSG, "Žádná složka nebyla nalezena. Zkusíme ostatní sériová čísla na panelu.");
// nenašly jsme složku, která odpovídá načtenému SN, zkusíme ostatní SN na panelu
barcode = FindCorrectBarcode(PrepareBarcodes(GetAllPossibleBarcodes()), directories);
if (barcode is null)
{
// složka neexistuje
s |= SGLMState.ResetLevel;
Session.Part.Clear();
Message = Log(LogMsg.AOI_DirectoryNotFound);
return s;
}
foreach (string path in directories) // našli jsme barcode, který odpovídá názvu nějaké složky
{
if (path.Contains(barcode.Item1))
{
directoriesWithBarcode.Add(path);
}
}
}
for (int i = 0; i < directoriesWithBarcode.Count(); i++) // hledání složky, s nejnovějším časem modifikace
{
DirectoryInfo dirInfo = new DirectoryInfo(directoriesWithBarcode[i]);
if (dirInfo.LastWriteTimeUtc > lastWriteTime)
{
lastWriteTime = dirInfo.LastWriteTimeUtc;
indexOfDirectory = i;
}
}
Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Nalezena složka {directoriesWithBarcode[indexOfDirectory]}");
m_correctBarcode = GetCorrectBarcode(barcode, directoriesWithBarcode[indexOfDirectory]);
// sestaveni spravne cesty k souborum se spravnymi nazvy
string bfreFile = string.Concat("DATA_", m_correctBarcode, ".bfre");
string bzmdFile = string.Concat(m_correctBarcode, ".bzmd");
string pathToFolder = Path.Combine(m_ngTestFilePath, Session.ProcessContext.SakiCustomer, Session.ProcessContext.SakiProgramName, Path.Combine("Lot", m_correctBarcode));
string pathToBfreFile = Path.Combine(pathToFolder, bfreFile);
string pathToBzmdFile = Path.Combine(pathToFolder, bzmdFile);
Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Hledám soubor {pathToBzmdFile} a {pathToBfreFile}");
bool filesExists = false;
int numOfTries = Session.ProcessContext.NumOfTriesForOpenFile;
do
{
if ((File.Exists(pathToBfreFile) == false) || (File.Exists(pathToBzmdFile) == false))
{
Thread.Sleep(Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile);
numOfTries--;
Log(LogMsg.CUSTOM_WARNING_MSG, $"Nenašel jsem bfre nebo bzmd soubor. Počet zbývajících pokusů: {numOfTries}");
}
else
{
filesExists = true;
}
} while (!filesExists && (numOfTries > 0));
if (!filesExists)
{
s |= SGLMState.ResetLevel;
Session.Part.Clear();
if (Directory.Exists(pathToFolder))
{
try
{
Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Obsah složky {pathToFolder} je {string.Join(",\n", Directory.GetFiles(pathToFolder))}");
}
catch (Exception e)
{
Message = Log(LogMsg.CUSTOM_WARNING_MSG, $"Nepodařilo se získat soubory ze složky {pathToFolder} chyba typu {e.Message}");
}
}
Message = Log(LogMsg.AOI_FileNotFound);
return s;
}
SakiResult dataFromFiles = new SakiResult();
Message = Log(LogMsg.FILE_TryOpen, pathToBfreFile);
if (FileHelper.TryParseFile(dataFromFiles.BfreData.ParseBfreFile, pathToBfreFile, Session.ProcessContext.NumOfTriesForOpenFile, Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile, LogErrorFromTryOpenFile) == false) // pro zjisteni zda jiz nebylo rozhodnuto
{
s |= SGLMState.ResetLevel;
Session.Part.Clear();
Message = Log(LogMsg.FILE_ERROR, pathToBfreFile);
Session.Part.Clear();
return s;
}
if (dataFromFiles.BfreData.JudgementResult == OK) // nekdo z nejakeho duvodu nacetl dil, ktery byl vyhodnocen strojem jako OK
{
s |= SGLMState.OK | SGLMState.UpLevel;
Session.Part.DoPart.SaveProcessData("Byl kontrolován již OK díl!", string.Empty, PartDataStatus.OK);
return s;
}
Message = Log(LogMsg.FILE_TryOpen, pathToBzmdFile);
if (FileHelper.TryParseFile(dataFromFiles.BzmdData.ParseBzmdFile, pathToBzmdFile, false, Session.ProcessContext.NumOfTriesForOpenFile, Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile, LogErrorFromTryOpenFile) == false) // pro vypsani udaju kolik je potrebnych rozhodnuti operatora
{
s |= SGLMState.ResetLevel;
Message = Log(LogMsg.FILE_ERROR, pathToBfreFile);
Session.Part.Clear();
return s;
}
if (WaitForFileUpdate(dataFromFiles, pathToFolder, bfreFile, pathToBfreFile) == false) // cekame dokud operator nerozhodne o povaze chyb
{
s |= SGLMState.ResetLevel;
Session.Part.Clear();
Message = Log(LogMsg.FILE_ERROR, pathToBfreFile + " zpracování dílu bylo přerušeno.");
Session.Part.Clear();
return s;
}
Log(LogMsg.FILE_ReadFile, pathToBfreFile, "bfre");
if (dataFromFiles.BfreData == null)
{
s |= SGLMState.ResetLevel;
Session.Part.Clear();
Message = Log(LogMsg.FILE_ERROR, pathToBfreFile + " nepodařilo se zpracovat BFRE soubor.");
Session.Part.Clear();
return s;
}
SetErrorVariables(dataFromFiles);
// ziskani aktualizovanych udaju o povaze chyb po rozhodnuti operatora
dataFromFiles.BzmdData.Clear();
Message = Log(LogMsg.FILE_TryOpen, pathToBfreFile);
if (FileHelper.TryParseFile(dataFromFiles.BzmdData.ParseBzmdFile, pathToBzmdFile, false, Session.ProcessContext.NumOfTriesForOpenFile, Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile, LogErrorFromTryOpenFile) == false) // pro zjisteni zda jiz nebylo rozhodnuto
{
s |= SGLMState.ResetLevel;
Session.Part.Clear();
Message = Log(LogMsg.FILE_ERROR, string.Concat(pathToBfreFile, " druhe cteni"));
Session.Part.Clear();
return s;
}
Log(LogMsg.FILE_ReadFile, pathToBzmdFile, "bzmd");
subBoardNotes.Clear();
Session.ProcessContext.PcbDirection.PanelParts = Session.Part.DoPart.GetPanelParts();
// zapis chyb
bool isPanelOk = true; // pro zjištění zda se bude ukládat fotka celého panelu, ve které by měly být vyznačeny chyby
foreach (SakiTestResult oneTest in dataFromFiles.BzmdData.TestedPos.Where(x => x.ErrorWrite == true))
{
long subBoardOID = Session.Part.DoPart.PartID;
int subBoardNum = 0;
long correctTestIndex = 0;
if (Int32.TryParse(oneTest.SubReference, out subBoardNum) == false)
{
subBoardNum = 0;
Message = Log(LogMsg.AOI_NotParsedSubReference, oneTest.SubReference);
}
if (subBoardNum == 0)
{
// na sub_reference rovno 0 by měli být pouze nezajímavé informace ohledně panelu a badmarků
continue;
}
try
{
correctTestIndex = Session.ProcessContext.PcbDirection.GetTestIndex(subBoardNum - 1) - 1;
subBoardOID = Session.ProcessContext.PcbDirection.GetPartOID(correctTestIndex);
}
catch (Exception)
{
correctTestIndex = 0;
subBoardOID = Session.Part.DoPart.PartID;
Message = Log(LogMsg.PCBDIRECTION_PcbIndexNotFinded, subBoardNum);
}
WriteDivergence(oneTest.RefName, oneTest.ErrorType, oneTest.Bitmap, pathToFolder, oneTest.Result, subBoardOID);
if (oneTest.Result == FAIL)
{
//WriteDivrg((int)(correctTestIndex), oneTest);
isPanelOk = false; // alespoň jedna chyba byla vyhodnocena jak opravdová => je potřeba uložit fotku celého panelu
}
}
if (m_showMatrix == true)
{
Session.ProcessContext.AOI_Data.IsInformationLoaded = true; // zviditelneni jednotlivych desek v GUI
}
// hledání csv souboru, aby byl korektni pocet opportunities, pokud nenaleznu tak pouziju hodnotu z bzmd souboru, protoze je to lepsi jak nic
if (Int32.TryParse(dataFromFiles.BzmdData.Opportunities, out int numOfOpportunities) == false)
{
numOfOpportunities = 1;
}
bool isCsvFileFinded = false;
if (m_useCsvFileForOpportunities)
{
Tuple<bool, string> csvEx = CsvFileExists(GetCsvFilePaths(dataFromFiles.BfreData.CsvFileName, CorrectBackupFolder(dataFromFiles.BfreData.CsvDateTime)), dataFromFiles.BfreData, SearchCsvFileWithTimeOffset);
if (csvEx.Item1 == true)
{
Message = Log(LogMsg.FILE_TryOpen, csvEx.Item2);
if (FileHelper.TryParseFile(dataFromFiles.CsvData.ParseCsvFile, csvEx.Item2, Session.ProcessContext.NumOfTriesForOpenFile, Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile, LogErrorFromTryOpenFile) == true)
{
dataFromFiles.BzmdData.Opportunities = dataFromFiles.CsvData.NumberOfTests.ToString();
numOfOpportunities = dataFromFiles.CsvData.NumberOfTests;
isCsvFileFinded = true;
}
}
}
if (!m_useCsvFileForOpportunities || (m_useCsvFileForOpportunities && !isCsvFileFinded))
{
if (m_useCsvFileForOpportunities) Message = Log(LogMsg.CUSTOM_WARNING_MSG, "Nepodařilo se najít soubor csv. Pokusíme se počet opportunities nalézt v databázi.");
int opportunities = m_aoiSakiSvc.GetOpportunitiesForPartID(m_cDataDL, (ex) => Message = Log(LogMsg.CUSTOM_WARNING_MSG, $"V databázi se nepodařilo najít záznam pro PartID: {Session.Part.DoPart.PartID}, JobID: {Session.Job.GetEffectiveDOJob().JobID}, JobRoutingPosIndex: {Session.CycleContext.OperationOverride.RoutingPosIndex}. Chyba {ex.Message}"), Session.Part.DoPart.PartID, Session.Job.GetEffectiveDOJob().JobID, Session.CycleContext.OperationOverride.RoutingPosIndex);
if (opportunities > 0)
{
numOfOpportunities = opportunities;
}
else // údaj není ani v db
{
Message = Log(LogMsg.AOISAKI_OpportunitiesFromBfre);
Message = Log(LogMsg.AOISAKI_CsvFileNotExists, dataFromFiles.BfreData.CsvFileName);
}
}
// aktualizace pocitadel pro alarmy
alarmVariablesFalseErrors.AddToVariables(numOfOpportunities, dataFromFiles.BzmdData.CountedResultFalseErrors, dataFromFiles.BzmdData.CountedResultError);
alarmVariablesDPMO.AddToVariables(numOfOpportunities, dataFromFiles.BzmdData.CountedResultFalseErrors, dataFromFiles.BzmdData.CountedResultError);
// pocitani zda se ma poslat alarm
FalseErrorAlarm(alarmVariablesFalseErrors);
DPMOAlarm(alarmVariablesDPMO);
// uložení obrázku celého panelu
SaveImageOfPanel(isPanelOk, pathToFolder);
SaveProcessData(dataFromFiles.BzmdData);
dataFromFiles.CsvData.Clear();
s |= SGLMState.OK | SGLMState.UpLevel;
return s;
}
private string GetCorrectBarcode(Tuple<string, bool> barcode, string correctDirectory)
{
Regex numberRegex = new Regex(string.Concat(barcode.Item1, @".*\((?<NumOfTest>[0-9]+)\)"));
if (numberRegex.IsMatch(correctDirectory)) // je to slozka s cislem testu
{
if (barcode.Item2) // SN je escapovano
{
return string.Concat("_{", barcode.Item1, "(", numberRegex.Match(correctDirectory).Groups["NumOfTest"].Value, ")}");
}
else
{
return string.Concat(barcode.Item1, "(", numberRegex.Match(correctDirectory).Groups["NumOfTest"].Value, ")");
}
}
else // je to slozka bez cisla testu
{
if (barcode.Item2)
{
return string.Concat("_{", barcode.Item1, "}");
}
else
{
return barcode.Item1;
}
}
}
/// <summary>
/// Metoda pro určení správné relativní cesty k zíloze souboru.
/// </summary>
/// <param name="dt"> Datum ze kterého se bere korektní složka se zálohou. </param>
/// <returns> Relativní část cesty označující cestu od původní složky ke složkám s měsíčními zálohami. Např. z cesty "C:\aoi\csv\backup\2020-10" je hodnota "backup\2020-10" </returns>
private string CorrectBackupFolder(DateTime dt)
{
return Path.Combine(m_csvFilePath, dt.ToString("yyyy-MM"));
}
/// <summary>
/// Metoda pro sestavení korektní cesty k souboru typu csv. Vrací cestu normální i cestu kde by měl být soubor zálohovaný.
/// </summary>
/// <param name="fileName"> Název csv souboru včetně přípony. </param>
/// <param name="correctBackupFolder"> Relativní část cesty označující cestu od původní složky ke složkám s měsíčními zálohami. Např. z cesty "C:\aoi\csv\backup\2020-10" je hodnota "backup\2020-10" </param>
/// <returns> Dvojice (string, string), kde první položka udává cestu k souboru na cestě se zálohou a druhý parametr udává cestu k souboru bez zálohy tj. tam kde se objevil. </returns>
private Tuple<string, string> GetCsvFilePaths(string fileName, string correctBackupFolder)
{
return new Tuple<string, string>(
Path.Combine(correctBackupFolder, fileName),
Path.Combine(m_csvOriginalFilePath, fileName));
}
/// <summary>
/// Metoda kontrolující existenci souboru z prvního parametru.
/// </summary>
/// <param name="csvLocations"> Dvojice (string, string), kde první položka udává cestu k souboru na cestě se zálohou a druhý parametr udává cestu k souboru bez zálohy tj. tam kde se objevil. </param>
/// <param name="dataFromBfreFile"> Objekt s daty získaných z bfre souboru. </param>
/// <param name="onFileNotExists"> Delegát pro zavolání funkce pro úpravu vyparserovaného času. </param>
/// <returns> Dvojice (bool, string), kde první položka udává úspěšnost nalezení souboru a když je true, pak druhá položka obsahuje cestu k souboru. </returns>
private Tuple<bool, string> CsvFileExists(Tuple<string, string> csvLocations, SakiBfreData dataFromBfreFile, Func<SakiBfreData, Tuple<bool, string>> onFileNotExists = null)
{
Message = Log(LogMsg.FILE_SearchFile, csvLocations.Item1);
if (File.Exists(csvLocations.Item1) == true)
{
return new Tuple<bool, string>(true, csvLocations.Item1);
}
Message = Log(LogMsg.FILE_SearchFile, csvLocations.Item2);
if (File.Exists(csvLocations.Item2) == true)
{
return new Tuple<bool, string>(true, csvLocations.Item2);
}
if (onFileNotExists != null)
{
return onFileNotExists(dataFromBfreFile);
}
return new Tuple<bool, string>(false, "");
}
/// <summary>
/// Metoda, která slouží k úpravě času, podle kterého se hledá soubor typu csv. Postupně přičítá/odečítá sekundy od původního údaje. Tato úprava se provádí podle hodnoty parametru "AddToCsvFileName".
/// </summary>
/// <param name="dataFromBfreFile"> Objekt s daty získaných z bfre souboru. </param>
/// <returns> Dvojice (bool, string), kde první položka udává úspěšnost nalezení souboru a když je true, pak druhá položka obsahuje cestu k souboru. </returns>
private Tuple<bool, string> SearchCsvFileWithTimeOffset(SakiBfreData dataFromBfreFile)
{
if (dataFromBfreFile.CsvDateTime == DateTime.MinValue) // z nejakeho duvodu se nepodarilo ziskat data pro jmeno csv souboru
{
return new Tuple<bool, string>(false, "");
}
DateTime tempFileDtName;
Tuple<bool, string> val;
for (int i = 1; i <= m_addToCsvFileNameInterval; i++)
{
tempFileDtName = dataFromBfreFile.CsvDateTime.AddSeconds(i);
val = CsvFileExists(GetCsvFilePaths(GetCsvFileName(tempFileDtName), CorrectBackupFolder(tempFileDtName)), dataFromBfreFile);
if (val.Item1 == true)
{
return val;
}
tempFileDtName = dataFromBfreFile.CsvDateTime.AddSeconds(-i);
val = CsvFileExists(GetCsvFilePaths(GetCsvFileName(tempFileDtName), CorrectBackupFolder(tempFileDtName)), dataFromBfreFile);
if (val.Item1 == true)
{
return val;
}
}
return new Tuple<bool, string>(false, "");
}
/// <summary>
/// Metoda pro získání názvu csv souboru z údajů bfre souboru nebo upravený, protože soubor s údajem ze souboru neexistoval.
/// </summary>
/// <param name="dtOfFile"> Časový údaj získaný z bfre souboru nebo upravený, protože soubor s údajem ze souboru neexistoval. </param>
/// <returns> Název souboru včetně přípony. </returns>
private string GetCsvFileName(DateTime dtOfFile)
{
return string.Concat(dtOfFile.ToString("yyyyMMdd_HHmmss"), ".csv");
}
private void SaveProcessData(SakiBzmdData data)
{
if (data.CountedResultError == 0)
{
Session.Part.DoPart.MS = 1;
Session.Part.DoPart.SaveProcessData(data.ToString(), string.Empty, PartDataStatus.OK);
}
else
{
Session.Part.DoPart.MS = m_aoiNgGSStatus;
Session.Part.DoPart.SaveProcessData(data.ToString(), string.Empty, PartDataStatus.Fail);
}
}
/// <summary>
/// Metoda, ktera vytvori objekty, jenz si udrzuji hodnoty pro vypocet alarmu.
/// </summary>
private void InitializeAlarms()
{
double falseErrorBound = Convert.ToDouble(m_boundFalseError);
double dpmoBound = Convert.ToDouble(m_boundDPMO);
if (m_boundFalseError == 0)
{
falseErrorBound = Convert.ToDouble(Int32.Parse(Session.Job.DoProduct.GmsKatalogParams[m_falseErrorKatalogParam]));
}
alarmVariablesFalseErrors = new AOIAlarmVariables(falseErrorCheckInterval, falseErrorBound);
Session.ProcessContext.AOI_Data.FalseErrorBound = falseErrorBound;
if (m_boundDPMO == 0)
{
dpmoBound = Convert.ToDouble(Int32.Parse(Session.Job.DoProduct.GmsKatalogParams[m_DPMOKatalogParam]));
}
alarmVariablesDPMO = new AOIAlarmVariables(falseErrorCheckInterval, dpmoBound);
Session.ProcessContext.AOI_Data.DpmoBound = dpmoBound;
}
/// <summary>
/// Metoda starajici se o vyhledani spravneho kodu chyby, kodu pozice v databazi a naslednemu zapisu chyby do databaze.
/// </summary>
/// <param name="Position"> Pozice soucastky. </param>
/// <param name="Result"> Kod chyby. </param>
/// <param name="imagePath"> Cesta k obrazku. </param>
/// <param name="pathToFolder"> Cesta ke slozce ve ktere se nachazi obrazek. </param>
/// <param name="testComponentResult"> Vysledek testu. </param>
/// <param name="partID"> ID partu ke kteremu chceme zapsat chybu. </param>
private void WriteDivergence(string Position, string Result, string imagePath, string pathToFolder, string testComponentResult, long partID = 0)
{
string DivergenceCode = Result;
if (Position == null) Position = string.Empty;
string ComponentPositionID = Position;
using (m_dxSession.GetLock())
{
// ziskani kodu divergence
var DivgCode = new XPQuery<xdata.Divergence>(m_dxSession.Session).Where(d => d.MachineErrorCD == Result).Select(d => d.CommandBD).FirstOrDefault();
if (!string.IsNullOrEmpty(DivgCode))
{
DivergenceCode = DivgCode;
}
else // zjistena chyba neexistuje v databazi
{
Log(LogMsg.MACHINEERROR_NotFound, Result, m_divrgCode);
DivergenceCode = m_divrgCode;
}
// zjisteni zda dana pozice jiz existuje nebo zda je potreba ji vytvorit
long PositionInDB;
var p = (new XPQuery<xdata.Positions>(m_dxSession.Session)).FirstOrDefault(x => x.PositionCD == ComponentPositionID);
if (p == null)
{
// pokud dana pozice jeste neni v DB tak potreba vytvorit
xdata.Positions pos = new xdata.Positions(m_dxSession.Session);
pos.PositionCD = ComponentPositionID;
pos.PositionType = m_dxSession.Session.GetObjectByKey<xdata.PositionsType>(1L);
pos.Save();
Log(LogMsg.COMPONENT_PositionCreated, ComponentPositionID);
var position = (new XPQuery<xdata.Positions>(m_dxSession.Session)).FirstOrDefault(x => x.PositionCD == ComponentPositionID);
PositionInDB = position.OID;
}
else // pozice v databazi existuje
{
PositionInDB = p.OID;
}
Session.Part.DoPart.DivrgPositionID = PositionInDB;
if (!Session.Part.DoPart.GetDivrg(DivergenceCode))
{
Session.Part.DoPart.GetDivrg(m_divrgCode);
Message = Log(LogMsg.DIVERGENCE_DivergenceCodeNotExistsOrNotSpecifiedForWorkplaceGroup, DivergenceCode, m_divrgCode);
}
string correctImageName = UpdateImageName(imagePath);
if (correctImageName is null)
{
Log(LogMsg.AOI_WriteDiveregenceHelpMessage, partID, Session.Part.DoPart.PartID, Session.Part.DoPart.IsPanel, testComponentResult == FAIL ? "true" : "false", "OBRÁZEK SE NEPODAŘILO NAČÍST", Position, Result);
Message = Log(LogMsg.AOI_LogNotContainDivergenceImage, Position);
Session.Part.DoPart.ImageID = 0;
}
else
{
string pathToImage = Path.Combine(pathToFolder, correctImageName);
Log(LogMsg.AOI_WriteDiveregenceHelpMessage, partID, Session.Part.DoPart.PartID, Session.Part.DoPart.IsPanel, testComponentResult == FAIL ? "true" : "false", pathToImage, Position, Result);
if (File.Exists(pathToImage) == true)
{
byte[] imageInByteArray = ImageResize(pathToImage, m_resizedImagePercents); // zmena velikosti obrazku
Session.Part.DoPart.ImageID = Session.Part.DoPart.Fail_AddImage(pathToImage, image: imageInByteArray);
}
else
{
Message = Log(LogMsg.AOI_DivergenceImageDoesNotExists, correctImageName);
Session.Part.DoPart.ImageID = 0;
}
}
if (testComponentResult == FAIL)
{
Session.Part.DoPart.Fail(Result, SGConstants.DIVRG_STATUS_NOT_REPAIRED_NGAOI, partID: partID, productID: 0);
}
else if (testComponentResult == PASS)
{
Session.Part.DoPart.Fail(Result, SGConstants.DIVRG_STATUS_FALSE_FAIL, partID: partID, productID: 0);
}
}
}
/// <summary>
/// Metoda, ktera ke jmenu obrazku ziskaneho z logu prida suffix, ktery realny soubor opravdu ma. Vraci retezec s opravdovym jmenem souboru.
/// </summary>
/// <param name="imageName"> Jmeno obrazku vyparserovane z logu. </param>
/// <returns>
/// string obsahujici opravdove jmeno souboru
/// </returns>
private string UpdateImageName(string imageName)
{
if (string.IsNullOrEmpty(imageName) == true)
{
return null;
}
string nameWithoutExtension = Path.GetFileNameWithoutExtension(imageName);
string extension = Path.GetExtension(imageName);
return string.Concat(nameWithoutExtension, m_addToImageName, extension);
}
/// <summary>
/// Metoda pro vytvoreni filewatcheru ke konkretnimu souboru.
/// </summary>
/// <param name="path"> Cesta ke slozce, ve ktere se nachazi soubor. </param>
/// <param name="fileName"> Nazev souboru. </param>
private void CreateFileWatcher(string path, string fileName)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = fileName;
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
}
/// <summary>
/// Metoda pro zjisteni zmeny v souboru.
/// </summary>
private void OnChanged(object source, FileSystemEventArgs e)
{
m_changed = true;
}
/// <summary>
/// Metoda pro vypocet hodnoty falesnych chyb, pokud hodnota presahne zadanou mez, tak pokud je to pozadovano tak se posle alarm.
/// </summary>
/// <param name="alarmVar"> Objekt, ktery obsahuje promenne pro vypocet alarmu. </param>
public void FalseErrorAlarm(AOIAlarmVariables alarmVar)
{
if (alarmVar.ErrorsFalse == 0)
{
alarmVar.CountedValue = 0.0;
}
else
{
alarmVar.CountedValue = (Convert.ToDouble(alarmVar.ErrorsFalse) / (Convert.ToDouble(alarmVar.ErrorsFalse) + Convert.ToDouble(alarmVar.ErrorsReal))) * 100;
}
UpdateGUIFalseErrorAlarmVariables(alarmVar);
if (alarmVar.CountedValue >= alarmVar.Bound)
{
Log(LogMsg.AOI_FalseErrorsAlarm, m_sendFalseErrorAlarm ? "byl odeslán." : "nebyl odeslán.");
if (m_sendFalseErrorAlarm == true) // posli alarm na falesne chyby
{
SendAlarm(m_falseErrorAlarmCode, Session.Job.DoJob.Barcode, Session.Job.DoProduct.Barcode, string.Join(",", Session.UserWorkGroup.LoggedUsers.Select(u => u.Name)), alarmVar.Bound, Math.Round(alarmVar.CountedValue, 2, MidpointRounding.AwayFromZero), Session.WorkPlace.Name);
}
alarmVar.ClearVariables();
}
}
/// <summary>
/// Metoda pro vypocet hodnoty DPMO, pokud hodnota presahne zadanou mez, tak pokud je to pozadovano tak se posle alarm.
/// </summary>
/// <param name="alarmVar"> Objekt, ktery obsahuje promenne pro vypocet alarmu. </param>
public void DPMOAlarm(AOIAlarmVariables alarmVar)
{
if (alarmVar.Opportunities == 0)
{
alarmVar.CountedValue = 0.0;
}
else
{
alarmVar.CountedValue = ((Convert.ToDouble(alarmVar.ErrorsReal) / Convert.ToDouble(alarmVar.Opportunities)) * 1000000);
}
UpdateGUIDPMOAlarmVariables(alarmVar);
if (alarmVar.CountedValue >= alarmVar.Bound)
{
Log(LogMsg.AOI_DPMOAlarm, m_sendDPMOAlarm ? "byl odeslán." : "nebyl odeslán.");
if (m_sendDPMOAlarm == true) // posli alarm na DPMO
{
SendAlarm(m_DPMOAlarmCode, Session.Job.DoJob.Barcode, Session.Job.DoProduct.Barcode, string.Join(",", Session.UserWorkGroup.LoggedUsers.Select(u => u.Name)), alarmVar.Bound, Math.Round(alarmVar.CountedValue, 2, MidpointRounding.AwayFromZero), Session.WorkPlace.Name);
}
alarmVar.ClearVariables();
}
}
/// <summary>
/// Metoda pro posilani alarmu.
/// </summary>
/// <param name="alarmCD"> Kod alarmu. </param>
/// <param name="par"> Parametry, ktere se zobrazi v retezci alarmu. </param>
public void SendAlarm(string alarmCD, params object[] par)
{
if (string.IsNullOrEmpty(alarmCD)) return;
Session.Alarm.SendAlarm(Session.UserWorkGroup.MainUser.UserID, SGAlarmEventType.None, alarmCD, par);
}
/// <summary>
/// Metoda pro ziskani vsech barcodu nachazejicich se na panelu. Vraci list obsahujici vsechny barcody nachazejici se na panelu.
/// </summary>
/// <returns>
/// List<string> list obsahujici vsechny barcody nachazejici se na panelu
/// </returns>
private List<string> GetAllPossibleBarcodes()
{
return m_aoiSakiSvc.GetAllBarcodesOnPanel(m_dxSession, Session.Part.DoPart.PartID, (ex) => Log(LogMsg.CUSTOM_WARNING_MSG, ex.Message));
}
/// <summary>
/// Metoda, ktera rozhoduje zda je dil OK nebo je potreba jej zpracovat na druhem pracovisti.
/// </summary>
/// <returns>
/// SGLMState reprezentujici co se ma stat po dokonceni tohoto modulu
/// </returns>
private SGLMState AOICheckWorkplace()
{
SGLMState s = SGLMState.Handled;
if (Session.ProcessContext.SakiData.IsBypassMode)
{
Session.WorkPlaceSetting.InfoData.LastPartBarcode = Session.ProcessContext.SakiData.ManageCode;
return SGLMState.Handled | SGLMState.OK | SGLMState.UpLevel;
}
SakiCsvData dataFromFile = new SakiCsvData();
dataFromFile.Clone(Session.ProcessContext.SakiData);
Session.ProcessContext.SakiData.Clear();
dataFromFile.IsPanel = Session.Part.DoPart.IsPanel;
if (dataFromFile.IsPanel == true)
{
dataFromFile.NumOfPcbs = Session.Part.DoPart.GetPanelParts().Length;
}
else
{
dataFromFile.NumOfPcbs = 0;
}
if (Session.ProcessContext.SakiResultFilePathExists == true)
{
string pathToFile;
if (string.IsNullOrEmpty(dataFromFile.OriginalBarcode) == true)
{
pathToFile = Path.Combine(Session.ProcessContext.SakiResultFilePath, dataFromFile.ManageCode, String.Concat(dataFromFile.ManageCode, ".bzmd"));
}
else
{
pathToFile = Path.Combine(Session.ProcessContext.SakiResultFilePath, dataFromFile.OriginalBarcode, String.Concat(dataFromFile.OriginalBarcode, ".bzmd"));
}
if (File.Exists(pathToFile) == true)
{
SakiBzmdData bzmdFile = new SakiBzmdData();
if (FileHelper.TryParseFile(bzmdFile.ParseBzmdFile, pathToFile, false, Session.ProcessContext.NumOfTriesForOpenFile, Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile, LogErrorFromTryOpenFile))
{
dataFromFile.ComponentCount = bzmdFile.ComponentCount;
dataFromFile.InspectedComponent = bzmdFile.InspectedComponent;
}
else
{
dataFromFile.ComponentCount = string.Empty;
dataFromFile.InspectedComponent = string.Empty;
}
}
}
var opportunitiesSave = m_aoiSakiSvc.InsertOpportunitiesToDatabase(m_cDataDL, (ex) => Message = Log(LogMsg.CUSTOM_WARNING_MSG, $"Do databáze se nepodařilo vložit počet opportunities pro PartID: {Session.Part.DoPart.PartID}, JobID: {Session.Job.GetEffectiveDOJob().JobID}, JobRoutingPosIndex: {Session.CycleContext.OperationOverride.RoutingPosIndex}. Chyba {ex.Message}"), Session.Part.DoPart.PartID, Session.Job.GetEffectiveDOJob().JobID, Session.CycleContext.OperationOverride.RoutingPosIndex, Session.WorkPlace.WorkPlaceID, dataFromFile.NumberOfTests);
if (opportunitiesSave.Item1)
{
Log(LogMsg.CUSTOM_INFO_MSG, $"Opportunities byly vloženy do databáze pod klíčem {opportunitiesSave.Item2}. Počet nalezených opportunities je {dataFromFile.NumberOfTests}");
}
else
{
Log(LogMsg.CUSTOM_WARNING_MSG, $"Opportunities se nepodařilo vložit do databáze. Počet nalezených opportunities je {dataFromFile.NumberOfTests}");
}
if (dataFromFile.AiJudge != m_TestOK)
{
if (dataFromFile.ParsedResultFromTestResults)
{
Log(LogMsg.CUSTOM_INFO_MSG, $"Výsledek testu byl NG, ale počet chyb je 0, proto je díl vyhodnocen jako shoda.");
Session.Part.DoPart.SaveProcessData(dataFromFile.ToString(), string.Empty, PartDataStatus.OK);
s |= SGLMState.OK | SGLMState.UpLevel;
Session.Part.DoPart.MS = 1;
}
else
{
Session.Part.DoPart.SaveProcessData(dataFromFile.ToString(), string.Empty, PartDataStatus.Fail);
Message = Log(LogMsg.AOI_EvalutePart, Session.Part.CurBarcode, dataFromFile.NumberOfTests);
s |= SGLMState.OK | SGLMState.UpLevel;
Session.Part.DoPart.MS = m_aoiNgGSStatus;
}
}
else
{
Session.Part.DoPart.SaveProcessData(dataFromFile.ToString(), string.Empty, PartDataStatus.OK);
s |= SGLMState.OK | SGLMState.UpLevel;
Session.Part.DoPart.MS = 1;
}
if ((string.IsNullOrEmpty(Session.FileGuard.BackupPath) == false) && (string.IsNullOrEmpty(dataFromFile.ParsedFile) == false))
{
if (File.Exists(dataFromFile.ParsedFile))
{
string fileName = Path.GetFileName(dataFromFile.ParsedFile);
string backupFolder = fileName.Substring(0, 4) + "-" + fileName.Substring(4, 2); // bereme rok a měsíc z názvu souboru
string backupPath = Path.Combine(Session.FileGuard.BackupPath, backupFolder);
Message = Log(LogMsg.FILEBACKUP_TryBackupFile, dataFromFile.ParsedFile, backupPath);
if (!FileHelper.BackupFile(dataFromFile.ParsedFile, backupPath, Session.FileGuard.DeleteOrigin, OnBackupError))
{
Session.ProcessContext.FilesToBeBackuped.Enqueue(new Tuple<string, string>(dataFromFile.ParsedFile, backupPath));
}
}
}
if (dataFromFile.RecordID != 0)
{
if (m_aoiSakiSvc.SetRecordIsProcessedState(m_cDataDL, SetError, dataFromFile.RecordID, (int)PartProcessType.ProcessedOk))
{
Message = Log(LogMsg.CUSTOM_INFO_MSG, $"Stav záznamu s ID={dataFromFile.RecordID}, byl změněn na hodnotu {(int)PartProcessType.ProcessedOk}.");
}
else
{
Message = Log(LogMsg.CUSTOM_WARNING_MSG, $"Nepodařilo se změnit stav záznamu s ID={dataFromFile.RecordID}, zpracování souboru je přerušeno!");
}
}
return s;
}
/// <summary>
/// Metoda pro zjisteni nazvu zakaznika. Vraci retezec se jmenem zakaznika.
/// </summary>
/// <returns>
/// string retezec se jmenem zakaznika
/// </returns>
private string GetCustomer()
{
string customer = (from f in new XPQuery<Firm>(m_dxSession.Session)
where f.OID == Session.Job.DoJob.FirmID
select f.Name).FirstOrDefault();
return customer;
}
/// <summary>
/// Metoda, ktera ceka na dokonceni vyhodnoceni operatorem. Vraci true, pokud byl operatorem vyhodnocen a soubor ma korektni format, false pokud soubor nema korektni format nebo bylo zpracovani dilu preruseno operatorem pomoci tlacitka v GUI.
/// </summary>
/// <param name="dataFromFiles"> Objekt pro ulozeni vyparserovanych dat. </param>
/// <param name="pathToFolder"> Cesta ke slozce ve ktere cekame na zmenu v souboru. </param>
/// <param name="bfreFile"> Nazev souboru na jehoz zmenu cekame. </param>
/// <param name="pathToBfreFile"> Kompletni cesta k souboru. </param>
/// <returns>
/// true pokud ma soubor korektni strukturu
/// false pokud soubor nema korektni strukturu nebo zpracovani dilu bylo preruseno operatorem
/// </returns>
private bool WaitForFileUpdate(SakiResult dataFromFiles, string pathToFolder, string bfreFile, string pathToBfreFile)
{
while (dataFromFiles.BfreData.JudgementResult == "Empty")
{
Log(LogMsg.AOI_WaitForUpdate, dataFromFiles.BzmdData.CountedResultUnknown, Session.Part.DoPart.CurBarcode);
CreateFileWatcher(pathToFolder, bfreFile);
while (m_changed == false)
{
if (Session.ProcessContext.AOI_Data.CancelTest == true)
{
Session.ProcessContext.AOI_Data.CancelTest = false;
return false;
}
}
Thread.Sleep(2000);
dataFromFiles.BfreData.Clear();
if (FileHelper.TryParseFile(dataFromFiles.BfreData.ParseBfreFile, pathToBfreFile, Session.ProcessContext.NumOfTriesForOpenFile, Session.ProcessContext.WaitTimeBeforeAnotherTryToOpenFile, LogErrorFromTryOpenFile) == false)
{
return false;
}
}
m_changed = false;
return true;
}
private void SetErrorVariables(SakiResult dataFromFiles)
{
Session.ProcessContext.AOI_Data.ToDecide = dataFromFiles.BzmdData.CountedResultUnknown;
Session.ProcessContext.AOI_Data.FalseErrors = dataFromFiles.BzmdData.CountedResultFalseErrors;
Session.ProcessContext.AOI_Data.RealErrors = dataFromFiles.BzmdData.CountedResultError;
}
/// <summary>
/// Metoda, ktera v GUI updatuje hodnoty promennych pro alarm falesnych chyb.
/// </summary>
/// <param name="feVars"> Objekt obsahujici promenne alarmu pro falsene chyby. </param>
public void UpdateGUIFalseErrorAlarmVariables(AOIAlarmVariables feVars)
{
Session.ProcessContext.AOI_Data.CountedFalseErrorsFE = feVars.ErrorsFalse;
Session.ProcessContext.AOI_Data.CountedRealErrorsFE = feVars.ErrorsReal;
Session.ProcessContext.AOI_Data.FalseErrorAlarm = feVars.CountedValue;
}
/// <summary>
/// Metoda, ktera v GUI updatuje hodnoty promennych pro alarm DPMO.
/// </summary>
/// <param name="dpmoVars"> Objekt obsahujici promenne alarmu pro DPMO. </param>
public void UpdateGUIDPMOAlarmVariables(AOIAlarmVariables dpmoVars)
{
Session.ProcessContext.AOI_Data.CountedOpportunitiesDPMO = dpmoVars.Opportunities;
Session.ProcessContext.AOI_Data.CountedRealErrorsDPMO = dpmoVars.ErrorsReal;
Session.ProcessContext.AOI_Data.DpmoAlarm = dpmoVars.CountedValue;
}
/// <summary>
/// Metoda pro uložení obrázku celého panelu, která podle parametru modulu určuje zda je požadované obrázek uložit.
/// </summary>
/// <param name="isPanelOk"> Určení zda se na panelu nachází nějaká opravdová chyba nebo jsou všechny falešné. </param>
/// <param name="pathToFolder"> Cesta ke složce ve které se nachází obrázek celého panelu. </param>
private void SaveImageOfPanel(bool isPanelOk, string pathToFolder)
{
switch (m_savePanelImage)
{
case SavePanelImage.Error:
if ((isPanelOk == false) && (string.IsNullOrEmpty(m_panelPhotoFileName) == false))
{
Session.Part.DoPart.AddImage(File.ReadAllBytes(Path.Combine(pathToFolder, m_panelPhotoFileName)));
}
break;
case SavePanelImage.FalseError:
if (string.IsNullOrEmpty(m_panelPhotoFileName) == false)
{
Session.Part.DoPart.AddImage(File.ReadAllBytes(Path.Combine(pathToFolder, m_panelPhotoFileName)));
}
break;
case SavePanelImage.NotSave:
break;
default:
break;
}
}
/// <summary>
/// Metoda, ktera provede zmenu velikosti obrazku na X% puvodniho podle hodnoty X ziskane v OnSetParameters. Navratova hodnota je bytove pole reprezentujici zmenseny obrazek, pokud je zmenseni uspesne, nebo null pokud se zmenseni nepodarilo.
/// </summary>
/// <param name="path"> Cesta k souboru. </param>
/// <param name="percents"> Na jakou procentualni velikost se ma obrazek zmensit. </param>
/// <returns>
/// bytove pole reprezentujici zmenseny obrazek, pokud zmenseni dopadlo uspesne
/// null pokud nastala chyba
/// </returns>
public byte[] ImageResize(string path, int percents)
{
string extension = Path.GetExtension(path);
try
{
// zmenseni obrazku na zadane procento
int newWidth = 0;
int newHeight = 0;
using (var input = new Bitmap(path))
{
int originalWidth = input.Width;
int originalHeight = input.Height;
newWidth = (int)(originalWidth * percents) / 100;
newHeight = (int)(originalHeight * percents) / 100;
}
using (var result = new Bitmap(newWidth, newHeight))
{
using (var input = new Bitmap(path))
{
using (Graphics g = Graphics.FromImage((System.Drawing.Image)result))
{
g.DrawImage(input, 0, 0, newWidth, newHeight);
}
}
// vytvoreni bytoveho pole ze zmenseneho obrazku
using (var ms = new MemoryStream())
{
switch (extension.ToLower())
{
case ".jpeg":
case ".jpg":
result.Save(ms, ImageFormat.Jpeg);
break;
case ".bmp":
result.Save(ms, ImageFormat.Bmp);
break;
case ".gif":
result.Save(ms, ImageFormat.Gif);
break;
case ".png":
result.Save(ms, ImageFormat.Png);
break;
default:
return null;
}
return ms.ToArray();
}
}
}
catch { }
return null;
}
private void OnBackupError(Exception e) => Message = Log(LogMsg.FILE_FileBackupNotOk, e.Message);
private List<Tuple<string, bool>> PrepareBarcodes(List<string> barcodes)
{
List<Tuple<string, bool>> retVal = new List<Tuple<string, bool>>();
string tempSN = string.Empty;
string tempSNWithDigitRegex = string.Empty;
for (int i = 0; i < barcodes.Count; i++)
{
if (Session.ProcessContext.EscapeHelper.IsSerialNumberNormalizedRegex(barcodes[i], ref tempSN))
{
barcodes[i] = tempSN;
retVal.Add(new Tuple<string, bool>(tempSN, true));
}
else
{
retVal.Add(new Tuple<string, bool>(barcodes[i], false));
}
}
return retVal;
}
private Tuple<string, bool> FindCorrectBarcode(List<Tuple<string, bool>> barcodes, List<string> directories)
{
foreach (var barcode in barcodes)
{
foreach (var directory in directories)
{
Regex barcodeRegex = new Regex(barcode.Item1);
if (barcodeRegex.IsMatch(directory))
{
return barcode;
}
}
}
return null;
}
private void LogErrorFromTryOpenFile(string msg) => Message = Log(LogMsg.CUSTOM_WARNING_MSG, msg);
private void InitXPO(MSSQL cdata)
{
var cs = "XpoProvider=MSSqlServer;" + cdata.ConnectionString;
var dict = new ReflectionDictionary();
dict.GetDataStoreSchema(typeof(LaserBoard));
dict.GetDataStoreSchema(typeof(LaserBoardCode));
dict.GetDataStoreSchema(typeof(ParsedFile));
var provider = XpoDefault.GetConnectionProvider(cs, AutoCreateOption.SchemaAlreadyExists);
m_cDataDL = new ThreadSafeDataLayer(dict, provider);
}
#endregion
}
public enum SavePanelImage
{
Error,
FalseError,
NotSave,
}
}