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
///
/// Start
///
public readonly byte STX = 0x02;
///
/// Read Mode
///
public readonly byte MODE_Read = 0x8a;
///
/// Control Mode
///
public readonly byte MODE_Control = 0x89;
///
/// Default
///
public readonly byte MODE2 = 0x9f;
///
/// MCUL32 의 ID값
///
public byte MCUL_ID = 0x81;
///
/// Defualt
///
public readonly byte DPU_ID = 0x9f;
///
/// FFU Controller(LCU)의 첫번째 ID 값
/// ID가 1인 경우 10000001 (0x81)
///
public byte Start_LCU_ID = 0x81;
///
/// FFU Controller(LCU)의 마지막 ID 값
/// ID가 5인 경우 10000101 (0x85)
///
public byte End_LCU_ID = 0x81;
///
/// {MODE1+MODE2+ … + mmAq HSV} => 하위바이트
///
//public byte Check_Sum { get; set; }
///
/// End
///
public readonly byte EXT = 0x03;
#endregion
///
/// Channel, FFU Status
///
public Dictionary 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();
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 datas = new List();
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 datas = new List();
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;
}
}
///
/// Check Sum 계산 Method
///
/// Command byte 배열
///
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;
}
}
///
/// MCUL32에 연결되어 있는 FFU Status
///
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 SVHSV or PV
/// FFU Controller(LCU)의 ID 값
///
public int LCU_ID { get; private set; }
///
/// LCU의 지령 속도 값(RPM) 0 ~ 1400RPM (0x00 ~ 0x8C)
///
public int Data_SV { get; private set; }
///
/// LCU의 현재 속도 값(RPM)
///
public int Data_PV { get; private set; }
///
/// 압력센서 값 (단위 : mmAq)
///
public double mmAq { get; private set; }
///
/// 압력센서 값 Low
///
public byte mmAqLSV { get; private set; }
///
/// 압력센서 값 High
///
public byte mmAqHSV { get; private set; }
#endregion
#region Change Datas
///
/// Alarm, Status 변경 Method
///
/// AL_ST byte Data
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)
{
}
}
///
/// Data SV 변경.
///
/// Data_SV byte Data
public void SetData_SV(byte Data_SV)
{
this.Data_SV = Data_SV * 10;
}
///
/// Data PV 변경.
///
/// Data_PV byte Data
public void SetData_PV(byte Data_PV)
{
this.Data_PV = Data_PV * 10;
}
///
/// mmAq Data 변경
///
/// 압력센서 값(하위 바이트)
/// 압력센서 값(상위 바이트)
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
}
}