using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Windows.Media.Animation; using AR; using arCtl; using COMM; using Project.StateMachine; namespace Project { public partial class fMain { DateTime chargesynctime = DateTime.Now; DateTime agvsendstarttime = DateTime.Now; // 장치 연결 쓰레드 관련 private Thread deviceConnectionThread; private volatile bool isDeviceConnectionRunning = false; void ConnectSerialPort(arDev.arRS232 dev, string port, int baud, eVarTime conn, eVarTime conntry, eVarTime recvtime) { if (dev.IsOpen == false && port.isEmpty() == false) { var tsPLC = VAR.TIME.RUN(conntry); if (tsPLC.TotalSeconds > 5) { VAR.TIME.Update(conntry); try { VAR.TIME.Update(recvtime); //this.LastReceiveTime = DateTime.Now; dev.PortName = port; dev.BaudRate = baud; if (dev.Open()) { PUB.log.Add(port, "연결완료"); } else { var errmessage = dev.errorMessage; PUB.log.Add("ERROR-" + port, errmessage); } VAR.TIME.Update(conn); VAR.TIME.Update(conntry); } catch (Exception ex) { PUB.log.AddE(ex.Message); } } } else if (dev.PortName.Equals(port) == false) { PUB.log.Add(port, $"포트변경({dev.PortName}->{port})으로 연결 종료"); dev.Close(); VAR.TIME.Update(conntry); } } void ConnectSerialPort(Device.Xbee dev, string port, int baud, eVarTime conn, eVarTime conntry, eVarTime recvtime) { if (dev.IsOpen == false && port.isEmpty() == false) { var tsPLC = VAR.TIME.RUN(conntry); if (tsPLC.TotalSeconds > 5) { VAR.TIME.Update(conntry); try { VAR.TIME.Update(recvtime); //this.LastReceiveTime = DateTime.Now; dev.PortName = port; dev.BaudRate = baud; if (dev.Open()) { PUB.log.Add(port, "연결완료"); } else { var errmessage = dev.errorMessage; PUB.log.Add("ERROR-" + port, errmessage); } VAR.TIME.Update(conn); VAR.TIME.Update(conntry); } catch (Exception ex) { PUB.log.AddE(ex.Message); } } } else if (dev.PortName.Equals(port) == false) { PUB.log.Add(port, $"포트변경({dev.PortName}->{port})으로 연결 종료"); dev.Close(); VAR.TIME[(int)conntry] = DateTime.Now; ; } } // 장치 연결 쓰레드 시작 private void StartDeviceConnectionThread() { if (deviceConnectionThread == null || !deviceConnectionThread.IsAlive) { isDeviceConnectionRunning = true; deviceConnectionThread = new Thread(DeviceConnectionWorker); deviceConnectionThread.IsBackground = true; deviceConnectionThread.Name = "DeviceConnectionThread"; deviceConnectionThread.Start(); PUB.log.Add("DeviceConnection", "장치 연결 쓰레드 시작"); } } // 장치 연결 쓰레드 종료 private void StopDeviceConnectionThread() { if (deviceConnectionThread != null && deviceConnectionThread.IsAlive) { isDeviceConnectionRunning = false; if (!deviceConnectionThread.Join(2000)) // 2초 대기 { try { deviceConnectionThread.Abort(); } catch { } } PUB.log.Add("DeviceConnection", "장치 연결 쓰레드 종료"); } } // 장치 연결 처리 워커 (별도 쓰레드에서 실행) private void DeviceConnectionWorker() { while (isDeviceConnectionRunning) { try { if (PUB.sm.Step >= eSMStep.IDLE && PUB.sm.Step < eSMStep.CLOSING) { //agv connect ConnectSerialPort(PUB.AGV, PUB.setting.Port_AGV, PUB.setting.Baud_AGV, eVarTime.LastConn_AGV, eVarTime.LastConnTry_AGV, eVarTime.LastRecv_AGV); //xbee connect ConnectSerialPort(PUB.XBE, PUB.setting.Port_XBE, PUB.setting.Baud_XBE, eVarTime.LastConn_XBE, eVarTime.LastConnTry_XBE, eVarTime.LastRecv_XBE); //bms connect if (PUB.BMS.IsOpen == false) { var ts = VAR.TIME.RUN(eVarTime.LastConn_BAT); if (ts.TotalSeconds > 3) { Console.WriteLine($"bms connect to {PUB.setting.Port_BAT}"); PUB.BMS.PortName = PUB.setting.Port_BAT; PUB.BMS.Open(); VAR.TIME.Update(eVarTime.LastConn_BAT); VAR.TIME.Update(eVarTime.LastConnTry_BAT); } } else if (PUB.BMS.IsValid == false) { var ts = VAR.TIME.RUN(eVarTime.LastConnTry_BAT); if (ts.TotalSeconds > 10) { Console.WriteLine("bms auto disconnect"); PUB.BMS.Close(); VAR.TIME.Set(eVarTime.LastConn_BAT, DateTime.Now.AddSeconds(5)); } } } } catch (Exception ex) { PUB.log.AddE($"DeviceConnection: {ex.Message}"); } // 1초 대기 후 다시 체크 Thread.Sleep(1000); } } void sm_SPS(object sender, EventArgs e) { if (PUB.sm.Step < eSMStep.IDLE || PUB.sm.Step >= eSMStep.CLOSING) return; // 장치 연결 쓰레드가 실행 중이 아니면 시작 if (!isDeviceConnectionRunning) { StartDeviceConnectionThread(); } //지그비상태전송 if (PUB.XBE != null && PUB.XBE.IsOpen) { //일정간격으로 상태를 전송한다 if (PUB.XBE.LastStatusSendTime.Year == 1982) PUB.XBE.LastStatusSendTime = DateTime.Now.AddSeconds(1); var ts = DateTime.Now - PUB.XBE.LastStatusSendTime; if (ts.TotalSeconds >= PUB.setting.interval_xbe) { PUB.XBE.SendStatus(); } } //배터리쿼리 if (PUB.BMS != null && PUB.BMS.IsOpen) { if (PUB.BMS.lastSendTime.Year == 1982) PUB.BMS.lastSendTime = DateTime.Now.AddSeconds(1); var ts = DateTime.Now - PUB.BMS.lastSendTime; if (ts.TotalSeconds >= PUB.setting.interval_bms) { PUB.BMS.SendQuery(); } Update_BatteryWarnSpeak(); } } } }