321 lines
13 KiB
C#
321 lines
13 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Manager;
|
|
using AuroraACS;
|
|
using AuroraDeviceCommon.Utils;
|
|
using AuroraIO.AJINEXTEK;
|
|
using AuroraIO.Vendor.ACS;
|
|
using AuroraIO.Vendor.PAIX;
|
|
using Hermes;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using static AuroraIO.Vendor.PAIX.PAIXIO;
|
|
using ACSIO = AuroraIO.Vendor.ACS.ACSIO;
|
|
|
|
namespace AuroraIO
|
|
{
|
|
public enum eIOBoardType
|
|
{
|
|
Ajin,
|
|
PAIX,
|
|
ACS
|
|
}
|
|
|
|
public partial class IODevice : Device
|
|
{
|
|
protected Logger Log = new Logger("IODevcie");
|
|
private IConnConfig _connConfig;
|
|
protected readonly IAuroraEnvironment _auroraEnv;
|
|
private readonly bool _IsSimulBySetting;
|
|
public MicroTimer _monitorIOInterfaceMap = new MicroTimer();
|
|
|
|
private readonly Device _refDevice;
|
|
#warning IO Unit은 Interface만 담당해야 함으로 IO 정보를 가진 데이터는 IODevice에서 관리하도록 하는게 나을 것으로 생각
|
|
private bool[] _DI;
|
|
private bool[] _DO;
|
|
|
|
|
|
public IOUnit _iOUnit { get; set; }
|
|
|
|
public IODevice(IAuroraEnvironment auroraEnv, string deviceId, bool isSimul)
|
|
{
|
|
_auroraEnv = auroraEnv;
|
|
_IsSimulBySetting = isSimul;
|
|
DeviceId = deviceId;
|
|
//monitorIOInterfaceMap.OnTimeout = MonitorIOInterfaceMap;
|
|
|
|
}
|
|
|
|
public IODevice(IAuroraEnvironment auroraEnv, string deviceId, bool isSimul, Device refDevice = null)
|
|
{
|
|
_auroraEnv = auroraEnv;
|
|
_IsSimulBySetting = isSimul;
|
|
DeviceId = deviceId;
|
|
_refDevice = refDevice;
|
|
//monitorIOInterfaceMap.OnTimeout = MonitorIOInterfaceMap;
|
|
|
|
}
|
|
|
|
public class ChangeChecker
|
|
{
|
|
private static Dictionary<string, bool> mapping = new Dictionary<string, bool>();
|
|
public static bool IsChangedBool(string Resource, bool value, bool defaultVal = false)
|
|
{
|
|
if (mapping.ContainsKey(Resource) == false) {
|
|
mapping[Resource] = defaultVal;
|
|
return false;
|
|
}
|
|
|
|
if (mapping[Resource] == value) {
|
|
return false;
|
|
}
|
|
|
|
mapping[Resource] = value;
|
|
return true;
|
|
}
|
|
public static bool IsChangedBoolMonitoring(string Resource, bool value, bool MonitoringValue, bool defaultVal = false)
|
|
{
|
|
if (mapping.ContainsKey(Resource) == false) {
|
|
mapping[Resource] = defaultVal;
|
|
return false;
|
|
}
|
|
|
|
if (mapping[Resource] == value) {
|
|
return false;
|
|
}
|
|
|
|
mapping[Resource] = value;
|
|
|
|
if (mapping[Resource] == MonitoringValue)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void MonitorIOInterfaceMap()
|
|
{
|
|
//함수 내부에 IO 시나리오에 맞게 구현 필요, 인터락 처리 등..
|
|
|
|
//EMO Check, Main N2/CDA Alarm Check
|
|
if (_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.EMOSwitchFront))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.EMOSwitchBack)))
|
|
|| _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.MainCDAAlarm))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.MainN2Alarm)))) {
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.BuzzerOn)), true);
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampREDOn)), true);
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampGREENOn)), false);
|
|
_auroraEnv.ViewManager.SetTowerLamp(eTowerLamp.RED);
|
|
} else {
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.BuzzerOn)), false);
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampREDOn)), false);
|
|
}
|
|
|
|
//Door Open Check, Panel Temp Alarm, Fan Alarmm, Motor MC Check => Warning
|
|
if (_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen1))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen2))) ||
|
|
_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen3))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen4))) ||
|
|
_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.PanelTempAlarm))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.FanAlarm5))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.FanAlarm6)))
|
|
|| _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.FanAlarm7))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.FanAlarm8))) || !_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.L2MotorMCOn)))
|
|
) {
|
|
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampYELLOWOn)), true);
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampGREENOn)), false);
|
|
_auroraEnv.ViewManager.SetTowerLamp(eTowerLamp.ORANGE);
|
|
|
|
} else {
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampYELLOWOn)), false);
|
|
_iOUnit.WriteDoBit((Convert.ToInt32(ePDOAddress.TowerLampGREENOn)), true);
|
|
_auroraEnv.ViewManager.SetTowerLamp(eTowerLamp.GREEN);
|
|
}
|
|
|
|
//Door Lock Check
|
|
if (_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockCloseMonitoring)))) {
|
|
_auroraEnv.ViewManager.DoorLock(true);
|
|
} else {
|
|
_auroraEnv.ViewManager.DoorLock(false);
|
|
}
|
|
|
|
//Door Open PM
|
|
bool DoorOpen = _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen1))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen2))) ||
|
|
_iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen3))) || _iOUnit.ReadDiBit((Convert.ToInt32(ePDIAddress.DoorLockOpen4)));
|
|
if (ChangeChecker.IsChangedBool("Door", DoorOpen)) {
|
|
//EventID Class를 ILSOS에서 받아올수 없을듯.. IODef에 EventID를 선언해주고 ILSOS에 넘겨주자..
|
|
EventPublisher.Publish(new EventMessage("DoorInterlock", IODef.EVENT_DOOR_INTERLOCK, DoorOpen));
|
|
}
|
|
}
|
|
|
|
protected override int DoActivate(IDeviceConfig config)
|
|
{
|
|
_connConfig = config.ConnConfig;
|
|
var m_IOUnitConfig = config as IOUnitConfig;
|
|
IsSimul = m_IOUnitConfig.IsDeviceSimul || _IsSimulBySetting;
|
|
|
|
if (IsSimul) {
|
|
//test용
|
|
if (m_IOUnitConfig.BoardType == eIOBoardType.Ajin)
|
|
_iOUnit = new AjinIO();
|
|
else if (m_IOUnitConfig.BoardType == eIOBoardType.PAIX)
|
|
_iOUnit = new PAIXIO();
|
|
else if (m_IOUnitConfig.BoardType == eIOBoardType.ACS)
|
|
_iOUnit = new ACSIO(_refDevice, m_IOUnitConfig);
|
|
LoadIOTable();
|
|
return E1.OK;
|
|
} else {
|
|
if (m_IOUnitConfig.BoardType == eIOBoardType.Ajin) {
|
|
_iOUnit = new AjinIO();
|
|
} else if (m_IOUnitConfig.BoardType == eIOBoardType.PAIX) {
|
|
_iOUnit = new PAIXIO();
|
|
} else if (m_IOUnitConfig.BoardType == eIOBoardType.ACS) {
|
|
_iOUnit = new ACSIO(_refDevice, m_IOUnitConfig);
|
|
}
|
|
else {
|
|
Log.I(string.Format(""));
|
|
}
|
|
}
|
|
|
|
int nRet = _iOUnit.Open(m_IOUnitConfig.DIDOIP);
|
|
if (nRet != 0)
|
|
return nRet;
|
|
|
|
LoadIOTable();
|
|
|
|
nRet = _iOUnit.Initialize();
|
|
|
|
if (_iOUnit.IsConnected() && m_IOUnitConfig.BoardType == eIOBoardType.PAIX) {
|
|
//monitorTimer는 우선 하드코딩으로 구성, Config로 받아와도 됨
|
|
//_monitorIOInterfaceMap.UpdateRateUS = 50 * 1000;
|
|
//IO쪽 완료 되기 전까지 주석처리
|
|
//_monitorIOInterfaceMap.Start();
|
|
//SetMonitoringService(MonitorIOInterfaceMap, 100);
|
|
//StartMonitoringService();
|
|
}
|
|
|
|
if (_iOUnit.IsConnected() && m_IOUnitConfig.BoardType == eIOBoardType.ACS) {
|
|
SetMonitoringService(Monitoring, 50);
|
|
StartMonitoringService();
|
|
}
|
|
|
|
return nRet;
|
|
}
|
|
|
|
private void Monitoring()
|
|
{
|
|
ACSDevice acs = _refDevice as ACSDevice;
|
|
if (!acs.IsActivated)
|
|
return;
|
|
|
|
if (_iOUnit.GetDiArray(ref _DI) != E1.OK)
|
|
return;
|
|
|
|
if (_iOUnit.GetDoArray(ref _DO) != E1.OK)
|
|
return;
|
|
}
|
|
public bool ReadDI(int index) => _iOUnit.ReadDiBit(index); // >> _ID 호출해도됨 _DI[index]
|
|
public bool ReadDO(int index) => _iOUnit.ReadDoBit(index); // >> _DO 호출해도됨 _DO[index]
|
|
public void WriteDO(int index, bool on) => _iOUnit.WriteDoBit(index, on);
|
|
|
|
protected override int DoDeactivate()
|
|
{
|
|
if (_iOUnit != null) {
|
|
_iOUnit.ClearList();
|
|
_iOUnit.Close();
|
|
}
|
|
StopMonitoringService();
|
|
return E1.OK;
|
|
}
|
|
|
|
public bool IsConnected()
|
|
{
|
|
if (_iOUnit == null) {
|
|
return false;
|
|
}
|
|
|
|
return _iOUnit.IsConnected();
|
|
}
|
|
|
|
public int LoadIOTable()
|
|
{
|
|
foreach (InfoIO.IoType type in Enum.GetValues(typeof(InfoIO.IoType))) {
|
|
if (type == InfoIO.IoType.EnumSize || type == InfoIO.IoType.AO || type == InfoIO.IoType.AI) continue;
|
|
|
|
MappingDIO(type);
|
|
}
|
|
return 0;
|
|
}
|
|
public int MappingDIO(InfoIO.IoType type)
|
|
{
|
|
try {
|
|
|
|
string fileName = "";
|
|
var m_connConfig = _connConfig as IOUnitConnConfig;
|
|
switch (type) {
|
|
case InfoIO.IoType.DI:
|
|
fileName = m_connConfig.IOInterfaceMapDI;
|
|
break;
|
|
case InfoIO.IoType.DO:
|
|
fileName = m_connConfig.IOInterfaceMapDO;
|
|
break;
|
|
//case InfoIO.IoType.AI:
|
|
// fileName = m_connConfig.IOInterfaceMapAI;
|
|
// break;
|
|
//case InfoIO.IoType.AO:
|
|
// fileName = m_connConfig.IOInterfaceMapAO;
|
|
// break;
|
|
default:
|
|
break;
|
|
//case InfoPlcIO.PlcIoType.SI:
|
|
// fileName = m_connConfig.PLCInterfaceMapSI;
|
|
// break;
|
|
//case InfoPlcIO.PlcIoType.SO:
|
|
// fileName = m_connConfig.PLCInterfaceMapSO;
|
|
// break;
|
|
}
|
|
|
|
FileInfo fi = new FileInfo(fileName);
|
|
|
|
if (!fi.Directory.Exists) {
|
|
fi.Directory.Create();
|
|
}
|
|
|
|
|
|
if (File.Exists(fileName) == false) {
|
|
Log.I(string.Format($"파일({fileName})이 존재하지 않습니다. Device Config의 File 경로를 확인하세요."));
|
|
|
|
return 0;
|
|
//StreamWriter writer = new StreamWriter(fileName, false, System.Text.Encoding.Unicode);
|
|
//writer.WriteLine("Index,Address,ID,IoType,ActiveLevel,BoardNo,Description,HighNecCond,LowNecCond,HighSensor,LowSensor,WaitInterlockTimeOut,WaitSensorTimeOut,HighSufCond,LowSufCond");
|
|
//writer.Close();
|
|
}
|
|
|
|
StreamReader sr = new StreamReader(fileName, System.Text.Encoding.Default);
|
|
string header = sr.ReadLine();
|
|
int index = 0;
|
|
while (sr.Peek() > -1) {
|
|
InfoIO dio = new InfoIO();
|
|
string[] temp = sr.ReadLine().ToString().Split(',');
|
|
|
|
if (dio.ConvertIOInfo(temp) == false) {
|
|
throw new Exception(string.Format("{0}.csv file {1}line data length wrong!!"));
|
|
}
|
|
|
|
if (type == InfoIO.IoType.DI)
|
|
_iOUnit.ListDI.Add(dio);
|
|
else if (type == InfoIO.IoType.DO)
|
|
_iOUnit.ListDO.Add(dio);
|
|
//else if (type == InfoIO.IoType.AI)
|
|
// ListAI.Add(dio);
|
|
//else if (type == InfoIO.IoType.AO)
|
|
// ListAO.Add(dio);
|
|
|
|
index++;
|
|
}
|
|
sr.Close();
|
|
|
|
return 0;
|
|
} catch {
|
|
throw;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|