using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
|
namespace SA_LTT.Module
|
{
|
public class FFU : ComPort
|
{
|
#region define Packet
|
|
/// <summary>
|
/// Start
|
/// </summary>
|
public readonly byte STX = 0x02;
|
|
/// <summary>
|
/// Read Mode
|
/// </summary>
|
public readonly byte MODE_Read = 0x8a;
|
|
/// <summary>
|
/// Control Mode
|
/// </summary>
|
public readonly byte MODE_Control = 0x89;
|
|
/// <summary>
|
/// Default
|
/// </summary>
|
public readonly byte MODE2 = 0x9f;
|
|
/// <summary>
|
/// MCUL32 의 ID값
|
/// </summary>
|
public byte MCUL_ID = 0x81;
|
|
/// <summary>
|
/// Defualt
|
/// </summary>
|
public readonly byte DPU_ID = 0x9f;
|
|
/// <summary>
|
/// FFU Controller(LCU)의 첫번째 ID 값
|
/// ID가 1인 경우 10000001 (0x81)
|
/// </summary>
|
public byte Start_LCU_ID = 0x81;
|
|
/// <summary>
|
/// FFU Controller(LCU)의 마지막 ID 값
|
/// ID가 5인 경우 10000101 (0x85)
|
/// </summary>
|
public byte End_LCU_ID = 0x81;
|
|
/// <summary>
|
/// {MODE1+MODE2+ … + mmAq HSV} => 하위바이트
|
/// </summary>
|
//public byte Check_Sum { get; set; }
|
|
/// <summary>
|
/// End
|
/// </summary>
|
public readonly byte EXT = 0x03;
|
|
#endregion
|
|
/// <summary>
|
/// Channel, FFU Status
|
/// </summary>
|
public Dictionary<int, FFUStatus> FFU_Status { get; }
|
|
private Equipment _equipment;
|
private Thread t_statusUpdate;
|
public FFU(Equipment equipment)
|
{
|
serialPort.PortName = "COM8";
|
serialPort.BaudRate = 9600;
|
serialPort.Parity = System.IO.Ports.Parity.None;
|
serialPort.DataBits = 8;
|
serialPort.StopBits = System.IO.Ports.StopBits.One;
|
Terminator = null;
|
|
FFU_Status = new Dictionary<int, FFUStatus>();
|
FFU_Status.Add(1, new FFUStatus(1));
|
|
_equipment = equipment;
|
t_statusUpdate = new Thread(statusUpdate);
|
t_statusUpdate.Start();
|
}
|
|
public void statusUpdate()
|
{
|
while (_equipment.IsDisposed == false)
|
{
|
try
|
{
|
Thread.Sleep(50);
|
|
if (IsOpen)
|
{
|
foreach(int key in FFU_Status.Keys)
|
{
|
// Todo. Command 설정.
|
ReadFFUStatus(key);
|
}
|
}
|
else
|
{
|
if (_equipment.alarmManager.OccurredAlarms.Exists(x => x.Code == AlarmCode.AL_0055_FFU_DISCONNECTED))
|
{
|
|
}
|
else
|
{
|
if (Open() == false)
|
{
|
_equipment.alarmManager.Occur(AlarmCode.AL_0055_FFU_DISCONNECTED);
|
}
|
}
|
}
|
}
|
catch (Exception e)
|
{
|
EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace);
|
}
|
}
|
}
|
|
public bool ReadFFUStatus(int address)
|
{
|
try
|
{
|
if (!FFU_Status.ContainsKey(address))
|
return false;
|
|
byte Start_LCU_ID = (byte)(address | 0x80);
|
byte End_LCU_ID = (byte)(address | 0x80);
|
|
List<byte> datas = new List<byte>();
|
datas.Clear();
|
|
datas.Add(MODE_Control);
|
datas.Add(MODE2);
|
datas.Add(MCUL_ID);
|
datas.Add(DPU_ID);
|
datas.Add(Start_LCU_ID);
|
datas.Add(End_LCU_ID);
|
datas.Add(GetCheckSum(datas.ToArray()));
|
datas.Insert(0, STX);
|
datas.Add(EXT);
|
|
byte[] rcvData;
|
|
//Todo. Write read 반환 값 Test 해야 댐.
|
//if (WriteRead(datas.ToArray(), out rcvData))
|
//{
|
// FFU_Status[address].SetData_PV(rcvData[6]);
|
// FFU_Status[address].ChangeStatus(rcvData[7]);
|
// FFU_Status[address].SetData_SV(rcvData[8]);
|
// FFU_Status[address].SetmmAq(rcvData[9], rcvData[10]);
|
|
// return true;
|
//}
|
//else
|
// return false;
|
|
return true;
|
}
|
catch (Exception e)
|
{
|
EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace);
|
return false;
|
}
|
}
|
|
public bool WritemmAqSV(double mmAq)
|
{
|
mmAq *= 100;
|
|
try
|
{
|
if (!FFU_Status.ContainsKey(1))
|
return false;
|
|
int a = (int)(mmAq);
|
|
string data = a.ToString("x");
|
|
byte daH, daL;
|
|
if (data.Length > 4)
|
return false;
|
|
if (data.Length == 4)
|
{
|
daH = Convert.ToByte(data.Substring(0, 2), 16);
|
daL = Convert.ToByte(data.Substring(2, 2), 16);
|
}
|
else if (data.Length == 3)
|
{
|
daH = Convert.ToByte(data.Substring(0, 1), 16);
|
daL = Convert.ToByte(data.Substring(1, 2), 16);
|
}
|
else
|
{
|
daH = 0x00;
|
daL = Convert.ToByte(data, 16);
|
}
|
|
List<byte> datas = new List<byte>();
|
datas.Clear();
|
|
datas.Add(MODE_Control); //89
|
datas.Add(MODE2); //9f
|
datas.Add(MCUL_ID); //81
|
datas.Add(DPU_ID); //9f
|
datas.Add(Start_LCU_ID); //81
|
datas.Add(End_LCU_ID); //82
|
datas.Add(daL); //01
|
datas.Add(daH); //00
|
datas.Add(daL); //00
|
datas.Add(daH); //00
|
datas.Add(daL); //32
|
datas.Add(daH); //00
|
datas.Add(GetCheckSum(datas.ToArray())); //7e
|
datas.Insert(0, STX); //02
|
datas.Add(EXT); //03
|
|
string recvData;
|
|
if (WriteRead(datas.ToArray(), out recvData))
|
{
|
byte[] bytesData = Encoding.Default.GetBytes(recvData);
|
foreach (byte bb in recvData)
|
{
|
if (bb == 0xb9)
|
return true;
|
}
|
}
|
|
return false;
|
}
|
catch (Exception e)
|
{
|
EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace);
|
return false;
|
}
|
}
|
|
/// <summary>
|
/// Check Sum 계산 Method
|
/// </summary>
|
/// <param name="datas">Command byte 배열</param>
|
/// <returns></returns>
|
public byte GetCheckSum(byte[] datas)
|
{
|
int sum = 0;
|
|
foreach (byte data in datas)
|
{
|
sum += data;
|
}
|
|
string proc_data = sum.ToString("x");
|
|
proc_data = proc_data.Substring(proc_data.Length - 2, 2);
|
|
byte value = Convert.ToByte(proc_data, 16);
|
|
return value;
|
}
|
|
public bool WriteRead(string command, out string receivedData)
|
{
|
string data = base.WriteRead(command + '\r');
|
|
if (data.StartsWith(command.Split(' ')[0]))
|
{
|
receivedData = data.Remove(0, command.Split(' ')[0].Length).Replace("\n\r", "");
|
return true;
|
}
|
else
|
{
|
receivedData = string.Empty;
|
return false;
|
}
|
}
|
|
public bool WriteRead(byte[] command, out string receivedData)
|
{
|
string data = base.WriteRead(command);
|
|
receivedData = data;
|
|
return true;
|
}
|
}
|
|
/// <summary>
|
/// MCUL32에 연결되어 있는 FFU Status
|
/// </summary>
|
public class FFUStatus
|
{
|
public enum AL_ST_Datas
|
{
|
Remote_Control_Mode = 0x80,
|
Local_Control_Mode = 0x81,
|
Thermal_Relay_Alarm = 0x82,//Not used
|
Open_the_door = 0x84,//Not used
|
Setting_Alarm = 0x88,//(SV>Max or SV<Min) - LIU MODE
|
RPM_Alarm = 0x90,//(PV>HSV or PV<LSV) - LIU MODE
|
Auto_controlling_for_Over_Current = 0xA0, //과전류
|
Over_Current_Alarm = 0xC0, //Motor Alarm
|
No_Connection_LCU = 0x00, //통신 Alarm
|
}
|
|
public FFUStatus(int LCU_ID)
|
{
|
this.LCU_ID = LCU_ID;
|
}
|
|
#region Status
|
public bool Remote_Control_Mode { get; private set; }
|
public bool Local_Control_Mode { get; private set; }
|
public bool Thermal_Relay_Alarm { get; private set; } //Not used
|
public bool Open_the_door { get; private set; } //Not used
|
public bool Setting_Alarm { get; private set; } //LIU MODE
|
public bool RPM_Alarm { get; private set; } //LIU MODE
|
public bool Auto_controlling_for_Over_Current { get; private set; }
|
public bool Over_Current_Alarm { get; private set; }
|
public bool No_Connection_LCU { get; private set; }
|
#endregion
|
|
#region Setting Parameter
|
|
/// <summary>
|
/// FFU Controller(LCU)의 ID 값
|
/// </summary>
|
public int LCU_ID { get; private set; }
|
|
/// <summary>
|
/// LCU의 지령 속도 값(RPM) 0 ~ 1400RPM (0x00 ~ 0x8C)
|
/// </summary>
|
public int Data_SV { get; private set; }
|
|
/// <summary>
|
/// LCU의 현재 속도 값(RPM)
|
/// </summary>
|
public int Data_PV { get; private set; }
|
|
/// <summary>
|
/// 압력센서 값 (단위 : mmAq)
|
/// </summary>
|
public double mmAq { get; private set; }
|
|
/// <summary>
|
/// 압력센서 값 Low
|
/// </summary>
|
public byte mmAqLSV { get; private set; }
|
|
/// <summary>
|
/// 압력센서 값 High
|
/// </summary>
|
public byte mmAqHSV { get; private set; }
|
#endregion
|
|
#region Change Datas
|
|
/// <summary>
|
/// Alarm, Status 변경 Method
|
/// </summary>
|
/// <param name="AL_ST">AL_ST byte Data</param>
|
public void ChangeStatus(byte AL_ST)
|
{
|
try
|
{
|
if ((AL_ST & (byte)AL_ST_Datas.Remote_Control_Mode) == (byte)AL_ST_Datas.Remote_Control_Mode) Remote_Control_Mode = true;
|
else Remote_Control_Mode = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.Local_Control_Mode) == (byte)AL_ST_Datas.Local_Control_Mode) Local_Control_Mode = true;
|
else Local_Control_Mode = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.Thermal_Relay_Alarm) == (byte)AL_ST_Datas.Thermal_Relay_Alarm) Thermal_Relay_Alarm = true;
|
else Thermal_Relay_Alarm = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.Open_the_door) == (byte)AL_ST_Datas.Open_the_door) Open_the_door = true;
|
else Open_the_door = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.Setting_Alarm) == (byte)AL_ST_Datas.Setting_Alarm) Setting_Alarm = true;
|
else Setting_Alarm = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.RPM_Alarm) == (byte)AL_ST_Datas.RPM_Alarm) RPM_Alarm = true;
|
else RPM_Alarm = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.Auto_controlling_for_Over_Current) == (byte)AL_ST_Datas.Auto_controlling_for_Over_Current) Auto_controlling_for_Over_Current = true;
|
else Auto_controlling_for_Over_Current = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.Over_Current_Alarm) == (byte)AL_ST_Datas.Over_Current_Alarm) Over_Current_Alarm = true;
|
else Over_Current_Alarm = false;
|
|
if ((AL_ST & (byte)AL_ST_Datas.No_Connection_LCU) == (byte)AL_ST_Datas.No_Connection_LCU) No_Connection_LCU = true;
|
else No_Connection_LCU = false;
|
}
|
catch (Exception)
|
{
|
|
}
|
}
|
|
/// <summary>
|
/// Data SV 변경.
|
/// </summary>
|
/// <param name="Data_SV">Data_SV byte Data</param>
|
public void SetData_SV(byte Data_SV)
|
{
|
this.Data_SV = Data_SV * 10;
|
}
|
|
/// <summary>
|
/// Data PV 변경.
|
/// </summary>
|
/// <param name="Data_PV">Data_PV byte Data</param>
|
public void SetData_PV(byte Data_PV)
|
{
|
this.Data_PV = Data_PV * 10;
|
}
|
|
/// <summary>
|
/// mmAq Data 변경
|
/// </summary>
|
/// <param name="mmAqLSV">압력센서 값(하위 바이트)</param>
|
/// <param name="mmAqHSV">압력센서 값(상위 바이트)</param>
|
public void SetmmAq(byte mmAqLSV, byte mmAqHSV)
|
{
|
try
|
{
|
this.mmAqHSV = mmAqHSV;
|
this.mmAqLSV = mmAqLSV;
|
string proc_mmAq = $"{mmAqHSV.ToString("x")}{mmAqLSV.ToString("x")}";
|
|
this.mmAq = Convert.ToInt32(proc_mmAq, 16) / 100.0;
|
}
|
catch (Exception)
|
{
|
|
}
|
}
|
#endregion
|
}
|
}
|