laatzen/Common/Ui/LegacyGenesisControl/ctlAutoDetect.cs
2021-10-01 11:09:20 +02:00

365 lines
11 KiB
C#

using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Xylem.Common.Utils.Logging;
namespace XylemCommonUiLegacyGenCtl
{
[Guid("34DE1F5F-BC96-4A28-9ED3-87C1A3E00920"),
ComVisible(true),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(ICtlAutoDetect))]
public partial class ctlAutoDetect : UserControl, ICtlAutoDetect
{
public delegate void OnSearchCompletedDelegate();
private event OnSearchCompletedDelegate OnSearchCompleted;
private CancellationTokenSource Stop = new CancellationTokenSource();
private Exception[] exs;
private int[] slots;
private MeterBatch batch = new MeterBatch();
private string[] slotStatus;
private string[] slotSerialNumbers;
private ILogger _logger;
private bool isDone = false;
public bool IsDone()
{
return isDone;
}
public ctlAutoDetect()
{
_logger = NLogHelper.CreateOrGetMultiLogger("ctlBatch", "", "Batch", "", "");
_logger.Info($"start construct ctlAutoDetect");
InitializeComponent();
}
public event EventHandler ErrorOnSlot;
public string GetErrorText(int Slot)
{
throw new NotImplementedException();
}
public string GetSerialNumber(int Slot)
{
var slotIndex = getSlotIndex(Slot);
if (slotIndex == -1 || slotSerialNumbers.Length <= slotIndex || slotSerialNumbers[slotIndex] == null)
{
_logger.Info($"GetSerialNumber for slot {Slot} return Empty");
return string.Empty;
}
_logger.Info($"GetSerialNumber for slot {Slot} return {slotSerialNumbers[slotIndex]}");
return slotSerialNumbers[slotIndex];
}
public void Init(int Slots)
{
_logger.Info($"Init {Slots} Slots");
slots = new Int32[Slots];
for (int i = 0; i < Slots; i++)
{
slots[i] = i + 1;
}
}
private Task searchTask = null;
public void Start()
{
if (searchTask == null || searchTask.IsCompleted)
{
Stop = new CancellationTokenSource();
isDone = false;
Invoke(new Action(() => { btnSearch.Enabled = false; btnTake.Enabled = false; }));
searchTask = new Task(() => { search(Stop.Token); }, Stop.Token);
searchTask.Start();
}
else
{
isDone = true;
}
}
private void UpdateUi()
{
var dgvData = new List<Object[]>();
foreach (var slot in slots)
{
var sr = slotStatus[getSlotIndex(slot)];
var ex = exs[getSlotIndex(slot)];
if (string.IsNullOrEmpty(sr))
{
sr = "None";
}
if (ex != null)
{
sr = $"{sr}[error]";
}
dgvData.Add(new Object[] { slot, sr });
}
Invoke(new Action(() =>
{
dgvDetect.Rows.Clear();
foreach (var data in dgvData)
{
dgvDetect.Rows.Add(data);
}
}));
}
private void btnSearch_Click(object sender, EventArgs e)
{
Start();
}
private int getSlotIndex(int Slot)
{
int r = 0;
foreach (var searchForSlot in slots)
{
if (Slot == searchForSlot)
{
return r;
}
r = r + 1;
}
return -1;
}
private void search(CancellationToken cancellation)
{
_logger.Info($"start search");
if (slots == null)
{
_logger.Info($"search was not initialized");
throw new ApplicationException("Not Init");
}
exs = new Exception[slots.Length];
slotStatus = new String[slots.Length];
slotSerialNumbers = new String[slots.Length];
var allSearchTask = new List<Task>();
if (batch != null)
{
batch.Dispose();
}
batch = new MeterBatch();
var sClone = slots.Clone();
foreach (var searchSlot in slots)
{
try
{
if (cancellation.IsCancellationRequested)
{
return;
}
var newTryMeter = new GenesisMeter();
_logger.Info($"Try to setup meter at slot {searchSlot}");
newTryMeter.SetupFromConfigFile(searchSlot);
batch.AddMeter(newTryMeter);
}
catch (Exception e)
{
slotStatus[getSlotIndex(searchSlot)] = "None";
exs[getSlotIndex(searchSlot)] = e;
_logger.Error(e, $"failed to setup slot setup task at slot {searchSlot}");
}
}
UpdateUi();
foreach (var meterslot in batch.ListOfMeters)
{
if (meterslot is GenesisMeter searchSlot)
{
try
{
var t = new Task(() =>
{
try
{
if (cancellation.IsCancellationRequested)
{
return;
}
SearchPcbId(searchSlot, searchSlot.Slot, cancellation);
}
catch (Exception e)
{
_logger.Error(e, $"failed to setup meter at slot {searchSlot.Slot}");
slotStatus[getSlotIndex(searchSlot.Slot)] = "None";
exs[getSlotIndex(searchSlot.Slot)] = e;
}
});
allSearchTask.Add(t);
}
catch (Exception e)
{
slotStatus[getSlotIndex(searchSlot.Slot)] = "None";
exs[getSlotIndex(searchSlot.Slot)] = e;
_logger.Error(e, $"failed to start slot setup task at slot {searchSlot.Slot}");
}
}
}
allSearchTask.ForEach(t => t.Start());
Task.WaitAll(allSearchTask.ToArray());
UpdateUi();
batch.Dispose();
batch = null;
_logger.Info($"Batch is disposed");
Invoke(new Action(() =>
{
btnSearch.Enabled = true;
btnTake.Enabled = true;
}));
}
private string GetPcbMapping(string pcbID)
{
if (string.IsNullOrEmpty(pcbID))
{
return "";
}
var url = $"{ServiceUrls.MarriageServiceUrl()}GetSerialNumberAndOrderNumber?PcbId={pcbID}";
try
{
var requestResponse = LocalWebRequest.GetRequest(url, 2000);
if (!string.IsNullOrEmpty(requestResponse))
{
var a = JsonConvert.DeserializeObject<string[]>(requestResponse);
return a[0];
}
else
{
return "";
}
}
catch (Exception ex)
{
if (ex is WebException)
{
//MessageBox.Show($"Error on Store: {Environment.NewLine} { ((WebException)ex).Message}");
}
_logger.Error(ex, $"failed to get pcb mapping for pcbid {pcbID}");
return "";
//MessageBox.Show(ex.Message);
}
}
private void SearchPcbId(GenesisMeter newTryMeter, int slot, CancellationToken cancellation)
{
try
{
if (cancellation.IsCancellationRequested)
{
return;
}
var firstPcbID = newTryMeter.GetPcbId();
if (cancellation.IsCancellationRequested)
{
return;
}
if (!string.IsNullOrEmpty(firstPcbID))
{
slotStatus[getSlotIndex(slot)] = $"detect {firstPcbID}";
var sr = GetPcbMapping(firstPcbID);
if (!string.IsNullOrEmpty(sr))
{
slotStatus[getSlotIndex(slot)] = $"found meter {sr}";
slotSerialNumbers[getSlotIndex(slot)] = sr;
}
else
{
slotStatus[getSlotIndex(slot)] = $"no mapping found for PCBId {firstPcbID}";
}
}
}
catch (Exception e)
{
_logger.Error(e, $"failed to search pcbid at slot {slot}");
exs[getSlotIndex(slot)] = e;
}
finally
{
batch?.RemoveMeter(newTryMeter);
}
}
public void Kill()
{
batch?.RemoveAllMeters();
batch.Dispose();
Dispose();
}
private void btnTake_Click(object sender, EventArgs e)
{
if (searchTask.Status == TaskStatus.Running || searchTask.Status == TaskStatus.WaitingToRun)
{
Stop.Cancel();
searchTask.Wait();
}
searchTask.Dispose();
isDone = true;
OnSearchCompleted?.Invoke();
//internalSerialNumberFound?.Invoke();
batch?.Dispose();
btnTake.Enabled = false;
}
private void dgvDetect_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void ctlAutoDetect_Load(object sender, EventArgs e)
{
}
}
}