434 lines
11 KiB
C#
434 lines
11 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using Aitex.Core.Common;
|
||
|
using Aitex.Core.RT.DataCenter;
|
||
|
using Aitex.Core.RT.Event;
|
||
|
using Aitex.Core.RT.Log;
|
||
|
using Aitex.Core.Util;
|
||
|
using Aitex.Sorter.RT.Module.DBRecorder;
|
||
|
using MECF.Framework.Common.Equipment;
|
||
|
using MECF.Framework.Common.Utilities;
|
||
|
|
||
|
namespace MECF.Framework.Common.SubstrateTrackings
|
||
|
{
|
||
|
public class CarrierManager : Singleton<CarrierManager>
|
||
|
{
|
||
|
private Dictionary<string, Dictionary<int, CarrierInfo>> _locationCarriers = new Dictionary<string, Dictionary<int, CarrierInfo>>();
|
||
|
|
||
|
private object _lockerCarrierList = new object();
|
||
|
|
||
|
private const string EventCarrierMoveIn = "CarrierMoveIn";
|
||
|
|
||
|
private const string EventCarrierMoveOut = "CarrierMoveOut";
|
||
|
|
||
|
private const string DvidCarrierId = "CarrierId";
|
||
|
|
||
|
private const string DvidStation = "Station";
|
||
|
|
||
|
public void Initialize()
|
||
|
{
|
||
|
EV.Subscribe(new EventItem("Event", "CarrierMoveIn", "carrier move in"));
|
||
|
EV.Subscribe(new EventItem("Event", "CarrierMoveOut", "carrier move out"));
|
||
|
Deserialize();
|
||
|
}
|
||
|
|
||
|
public void Terminate()
|
||
|
{
|
||
|
lock (_lockerCarrierList)
|
||
|
{
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Deserialize()
|
||
|
{
|
||
|
lock (_lockerCarrierList)
|
||
|
{
|
||
|
Dictionary<string, Dictionary<int, CarrierInfo>> dictionary = BinarySerializer<Dictionary<string, Dictionary<int, CarrierInfo>>>.FromStream("CarrierManager");
|
||
|
if (dictionary != null)
|
||
|
{
|
||
|
_locationCarriers = dictionary;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void Serialize()
|
||
|
{
|
||
|
lock (_lockerCarrierList)
|
||
|
{
|
||
|
if (_locationCarriers != null)
|
||
|
{
|
||
|
BinarySerializer<Dictionary<string, Dictionary<int, CarrierInfo>>>.ToStream(_locationCarriers, "CarrierManager");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void SubscribeLocation(string module, int capacity = 1)
|
||
|
{
|
||
|
lock (_lockerCarrierList)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module] = new Dictionary<int, CarrierInfo>();
|
||
|
for (int i = 0; i < capacity; i++)
|
||
|
{
|
||
|
_locationCarriers[module][i] = new CarrierInfo(25);
|
||
|
}
|
||
|
}
|
||
|
DATA.Subscribe(module, "Carrier", () => _locationCarriers[module][0]);
|
||
|
DATA.Subscribe(module.ToString(), "ModuleCarrierList", () => _locationCarriers[module].Values.ToArray());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void CreateCarrier(string module)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].Status = CarrierStatus.Normal;
|
||
|
_locationCarriers[module][0].InnerId = Guid.NewGuid();
|
||
|
_locationCarriers[module][0].Name = "Cassette" + DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
|
_locationCarriers[module][0].LoadTime = DateTime.Now;
|
||
|
CarrierDataRecorder.Loaded(_locationCarriers[module][0].InnerId.ToString(), module);
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void CreateCarrier(string module, ModuleName intCarmodulename, WaferSize size, int slotNumber)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].Status = CarrierStatus.Normal;
|
||
|
_locationCarriers[module][0].InnerId = Guid.NewGuid();
|
||
|
_locationCarriers[module][0].Name = "Cassette" + DateTime.Now.ToString("yyyyMMddHHmmss");
|
||
|
_locationCarriers[module][0].LoadTime = DateTime.Now;
|
||
|
_locationCarriers[module][0].InternalModuleName = intCarmodulename;
|
||
|
_locationCarriers[module][0].CarrierWaferSize = size;
|
||
|
if (!Singleton<WaferManager>.Instance.AllLocationWafers.ContainsKey(intCarmodulename))
|
||
|
{
|
||
|
Singleton<WaferManager>.Instance.SubscribeLocation(intCarmodulename, slotNumber);
|
||
|
}
|
||
|
CarrierDataRecorder.Loaded(_locationCarriers[module][0].InnerId.ToString(), module);
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void DeleteCarrier(string module)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
CarrierDataRecorder.Unloaded(_locationCarriers[module][0].InnerId.ToString());
|
||
|
_locationCarriers[module][0].Clear();
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void DeleteInternalCarrier(string module)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
CarrierDataRecorder.Unloaded(_locationCarriers[module][0].InnerId.ToString());
|
||
|
_locationCarriers[module][0].Clear();
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void RegisterCarrierWafer(string module, int index, WaferInfoRt wafer)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].Wafers[index] = wafer;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UnregisterCarrierWafer(string module, int index)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].Wafers[index] = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public CarrierInfo GetCarrier(string module)
|
||
|
{
|
||
|
return GetCarrier(module, 0);
|
||
|
}
|
||
|
|
||
|
public CarrierInfo GetCarrier(ModuleName module)
|
||
|
{
|
||
|
return GetCarrier(module.ToString(), 0);
|
||
|
}
|
||
|
|
||
|
public CarrierInfo GetCarrier(ModuleName module, int slot)
|
||
|
{
|
||
|
return GetCarrier(module.ToString(), slot);
|
||
|
}
|
||
|
|
||
|
public CarrierInfo GetCarrier(string module, int slot)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
return _locationCarriers[module][slot];
|
||
|
}
|
||
|
|
||
|
public CarrierInfo[] GetCarriers(string module)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
return _locationCarriers[module].Values.ToArray();
|
||
|
}
|
||
|
|
||
|
public string GetLocationByCarrierId(string carrierId)
|
||
|
{
|
||
|
foreach (KeyValuePair<string, Dictionary<int, CarrierInfo>> locationCarrier in _locationCarriers)
|
||
|
{
|
||
|
foreach (KeyValuePair<int, CarrierInfo> item in locationCarrier.Value)
|
||
|
{
|
||
|
if (!item.Value.IsEmpty && item.Value.CarrierId == carrierId)
|
||
|
{
|
||
|
return locationCarrier.Key;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public string GetLocationByInternalCarrierModuleName(ModuleName name)
|
||
|
{
|
||
|
foreach (KeyValuePair<string, Dictionary<int, CarrierInfo>> locationCarrier in _locationCarriers)
|
||
|
{
|
||
|
foreach (KeyValuePair<int, CarrierInfo> item in locationCarrier.Value)
|
||
|
{
|
||
|
if (!item.Value.IsEmpty && item.Value.InternalModuleName == name)
|
||
|
{
|
||
|
return locationCarrier.Key;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public string GetLotIdByLoadPort(string moduleName)
|
||
|
{
|
||
|
return _locationCarriers.ContainsKey(moduleName) ? _locationCarriers[moduleName][0].LotId : "";
|
||
|
}
|
||
|
|
||
|
public bool HasCarrier(string module, int slot = 0)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return !_locationCarriers[module][0].IsEmpty;
|
||
|
}
|
||
|
|
||
|
public bool CheckHasCarrier(string module, int slot)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return !_locationCarriers[module][0].IsEmpty;
|
||
|
}
|
||
|
|
||
|
public bool CheckHasCarrier(ModuleName module, int slot)
|
||
|
{
|
||
|
return CheckHasCarrier(module.ToString(), 0);
|
||
|
}
|
||
|
|
||
|
public bool CheckNoCarrier(string module, int slot)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return _locationCarriers[module][0].IsEmpty;
|
||
|
}
|
||
|
|
||
|
public bool CheckNoCarrier(ModuleName module, int slot)
|
||
|
{
|
||
|
return CheckNoCarrier(module.ToString(), slot);
|
||
|
}
|
||
|
|
||
|
public bool CheckNeedProcess(string module, int slot)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
if (_locationCarriers[module][0].IsEmpty)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
if (!_locationCarriers[module][0].HasWaferIn)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return !_locationCarriers[module][0].IsProcessCompleted;
|
||
|
}
|
||
|
|
||
|
public bool CheckNeedProcess(ModuleName module, int slot)
|
||
|
{
|
||
|
return CheckNeedProcess(module.ToString(), slot);
|
||
|
}
|
||
|
|
||
|
public bool CheckHasWaferIn(string module, int slot)
|
||
|
{
|
||
|
if (!_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
if (_locationCarriers[module][0].IsEmpty)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return _locationCarriers[module][0].HasWaferIn;
|
||
|
}
|
||
|
|
||
|
public bool CheckHasWaferIn(ModuleName module, int slot)
|
||
|
{
|
||
|
return CheckHasWaferIn(module.ToString(), slot);
|
||
|
}
|
||
|
|
||
|
public void CarrierMoved(string moduleFrom, string moduleTo)
|
||
|
{
|
||
|
if (_locationCarriers[moduleFrom][0].IsEmpty)
|
||
|
{
|
||
|
LOG.Write($"Invalid carrier move, no carrier at source, {moduleFrom}{1}=>{moduleTo}{1}");
|
||
|
return;
|
||
|
}
|
||
|
if (!_locationCarriers[moduleTo][0].IsEmpty)
|
||
|
{
|
||
|
LOG.Write($"Invalid carrier move, destination has carrier, {moduleFrom}{1}=>{moduleTo}{1}");
|
||
|
return;
|
||
|
}
|
||
|
_locationCarriers[moduleTo][0].CopyInfo(_locationCarriers[moduleFrom][0]);
|
||
|
DeleteCarrier(moduleFrom);
|
||
|
EV.Notify("CarrierMoveOut", new SerializableDictionary<string, string>
|
||
|
{
|
||
|
{
|
||
|
"CarrierId",
|
||
|
GetCarrier(moduleFrom).CarrierId
|
||
|
},
|
||
|
{ "Station", moduleFrom }
|
||
|
});
|
||
|
EV.Notify("CarrierMoveIn", new SerializableDictionary<string, string>
|
||
|
{
|
||
|
{
|
||
|
"CarrierId",
|
||
|
GetCarrier(moduleTo).CarrierId
|
||
|
},
|
||
|
{ "Station", moduleTo }
|
||
|
});
|
||
|
EV.PostInfoLog(ModuleName.System.ToString(), $"Carrier moved from {moduleFrom} to {moduleTo}");
|
||
|
Serialize();
|
||
|
}
|
||
|
|
||
|
public void UpdateCarrierId(string module, string carrierId)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
if (!string.IsNullOrEmpty(_locationCarriers[module][0].CarrierId))
|
||
|
{
|
||
|
DeleteCarrier(module);
|
||
|
CreateCarrier(module);
|
||
|
}
|
||
|
_locationCarriers[module][0].CarrierId = carrierId;
|
||
|
CarrierDataRecorder.UpdateCarrierId(_locationCarriers[module][0].InnerId.ToString(), carrierId);
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UpdateRfId(string module, string rfid)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
if (!string.IsNullOrEmpty(_locationCarriers[module][0].CarrierId))
|
||
|
{
|
||
|
DeleteCarrier(module);
|
||
|
CreateCarrier(module);
|
||
|
}
|
||
|
_locationCarriers[module][0].Rfid = rfid;
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UpdateCarrierLot(string module, string lotId)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].LotId = lotId;
|
||
|
CarrierDataRecorder.UpdateLotId(_locationCarriers[module][0].InnerId.ToString(), lotId);
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool UpdateWaferSize(ModuleName module, int slot, WaferSize size)
|
||
|
{
|
||
|
_locationCarriers[module.ToString()][slot].CarrierWaferSize = size;
|
||
|
Serialize();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public void UpdateProductCategory(string module, string productCategory)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].ProductCategory = productCategory;
|
||
|
CarrierDataRecorder.UpdateProductCategory(_locationCarriers[module][0].InnerId.ToString(), productCategory);
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UpdateProcessJob(string module, object job)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].ProcessJob = job;
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UpdateProcessStatus(string module, bool processed)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].ProcessStatus[module] = processed;
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UpdateProcessCompleted(ModuleName module, int slot, bool processed)
|
||
|
{
|
||
|
UpdateProcessCompleted(module.ToString(), slot, processed);
|
||
|
}
|
||
|
|
||
|
public void UpdateProcessCompleted(string module, int slot, bool processed)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].IsProcessCompleted = processed;
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void UpdateWaferIn(ModuleName module, int slot, bool waferIn)
|
||
|
{
|
||
|
UpdateWaferIn(module.ToString(), slot, waferIn);
|
||
|
}
|
||
|
|
||
|
public void UpdateWaferIn(string module, int slot, bool waferIn)
|
||
|
{
|
||
|
if (_locationCarriers.ContainsKey(module))
|
||
|
{
|
||
|
_locationCarriers[module][0].HasWaferIn = waferIn;
|
||
|
Serialize();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|