using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Threading; using COMM; using System.Runtime.Remoting.Messaging; using ENIG; using System.Security.Cryptography; using AR; using System.Web.Compilation; namespace Project.Device { public class Xbee : System.IO.Ports.SerialPort { public string buffer = string.Empty; public System.Text.StringBuilder newbuffer = new StringBuilder(); public string errorMessage = string.Empty; public DateTime LastStatusSendTime = DateTime.Now; private EEProtocol proto; public Xbee() { this.DataReceived += Xbee_DataReceived; proto = new EEProtocol(); proto.OnDataReceived += Proto_OnDataReceived; proto.OnMessage += Proto_OnMessage; } ~Xbee() { this.DataReceived -= Xbee_DataReceived; proto.OnDataReceived -= Proto_OnDataReceived; proto.OnMessage -= Proto_OnMessage; } /// /// AGV상태를 Xbee 로 전송한다 /// public void SendStatus() { /* Mode[1] : 0=manual, 1=auto RunSt[1] : 0=stop, 1=run, 2=error Diection[1] : 0=straight, 1=left, 2=right, 3=markstop Inposition[1] : 0=off, 1=on : 목적위치에 도달완료 시 설정 이동 이동시 OFF됨 ChargeSt[1] : 0=off, 1=on CartSt[1] : 0=off, 1=on, 2=unknown LiftSt[1] : 0=down , 1=up, 2=unknown LastTag[6] : "000000" */ try { byte[] data = new byte[13]; // 총 13바이트 데이터 // Mode data[0] = (byte)(VAR.BOOL[eVarBool.FLAG_AUTORUN] ? 1 : 0); // RunSt if (PUB.AGV.error.Emergency) data[1] = 2; // error else if (PUB.AGV.system1.agv_run) data[1] = 1; // run else data[1] = 0; // stop // Direction if (PUB.AGV.system1.stop_by_front_detect) data[2] = 3; // markstop else if (VAR.BOOL[eVarBool.FLAG_LEFT_RUN]) data[2] = 1; // left else if (VAR.BOOL[eVarBool.FLAG_RIGHT_RUN]) data[2] = 2; // right else data[2] = 0; // straight // Inposition data[3] = (byte)(PUB.AGV.system1.agv_stop ? 1 : 0); // ChargeSt data[4] = (byte)((VAR.BOOL[eVarBool.FLAG_CHARGEONA] || VAR.BOOL[eVarBool.FLAG_CHARGEONM]) ? 1 : 0); // CartSt if(PUB.AGV.signal.cart_detect1 && PUB.AGV.signal.cart_detect2) data[5] = 1; // 센서두개가 모두 감지되는 경우 else if(PUB.AGV.signal.cart_detect1==false && PUB.AGV.signal.cart_detect2==false) data[5] = 0; // 센서두개가 모두 감지되지 않는 경우 else data[5] = 2; // 센서하나만 감지되는 경우 // LiftSt if(PUB.AGV.signal.lift_up) data[6] = 1; // 위로 올라가는 경우 else if(PUB.AGV.signal.lift_down) data[6] = 0; // 아래로 내려가는 경우 else data[6] = 2; // unknown (기본값) // LastTag string lastTag = PUB.AGV.data.TagNo.ToString("000000") ?? "000000"; byte[] tagBytes = Encoding.ASCII.GetBytes(lastTag.PadRight(6, '0')); Array.Copy(tagBytes, 0, data, 7, 6); // 데이터 전송 var packet = proto.CreatePacket(PUB.setting.XBE_ID, 9, data); Send(packet); LastStatusSendTime = DateTime.Now; } catch (Exception ex) { errorMessage = ex.Message; PUB.logxbee.AddE(errorMessage); } } /// /// 지그비장치에 데이터를 전송합니다 /// /// /// public bool Send(byte[] data) { try { this.Write(data, 0, data.Length); return true; }catch (Exception ex) { errorMessage = ex.Message; return false; } } public new bool Open() { try{ this.Open(); return true; }catch (Exception ex) { errorMessage = ex.Message; PUB.logxbee.AddE(errorMessage); return false; } } private void Proto_OnDataReceived(object sender, EEProtocol.DataEventArgs e) { var hexstrRaw = e.ReceivedPacket.RawData.HexString(); var hexstr = e.ReceivedPacket.Data.HexString(); var cmd = e.ReceivedPacket.Command.ToString("X2"); var id = e.ReceivedPacket.ID.ToString("X2"); PUB.logxbee.Add("RX", $"{hexstrRaw}\nID:{id},CMD:{cmd},DATA:{hexstr}"); //TODO : 기능 처리필요 (XBee 메세지 데이터처리) //PUB.CheckManualChargeMode() : 수동충전확인 //VAR.BOOL[eVarBool.FLAG_AUTORUN] : 자동실행 //PUB.Speak("현재 위치는 QA 입니다.") : 음성출력 } private void Proto_OnMessage(object sender, EEProtocol.MessageEventArgs e) { if (e.IsError) PUB.log.AddE(e.Message); else PUB.log.Add(e.Message); } private void Xbee_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { var dev = sender as System.IO.Ports.SerialPort; var buffer = new byte[dev.BytesToRead]; dev.Read(buffer, 0, buffer.Length); proto.ProcessReceivedData(buffer); } } }