/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api; using Hermes; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Runtime.Remoting.Channels; using System.Text; using System.Threading; using System.Threading.Tasks; namespace VisionLight { /// /// Inkjet oleds 에서 검증 - LightLTPS /// Serial connection type #warning [TODO : Aurora 고정부 추가후 수정 필요] /// internal class Light_LVS_PT0105_raw : LightBase_Serial { public Light_LVS_PT0105_raw(string deviceId) : base(deviceId) { DeviceId = deviceId; LOG = new Logger(deviceId); } #region Implement Base interface & methods protected override int DoActivate(IDeviceConfig config) { if (IsSimul) return E1.OK; #warning [TODO : Aurora 고정부 추가후 수정 필요] //SerialPort.DataReceived += SerialPort_DataReceived; return base.DoActivate(config); } protected override int DoDeactivate() { #warning [TODO : Aurora 고정부 추가후 수정 필요] //SerialPort.DataReceived -= SerialPort_DataReceived; return base.DoDeactivate(); } protected override eLightResult SetLevelImpl(int level, int channel) { return SetLightValue(channel, level) ? eLightResult.OK : eLightResult.NG; } protected override eLightResult SetOffImpl(int channel) { return SetLightOnOff(channel, false) ? eLightResult.OK : eLightResult.NG; } protected override eLightResult SetOnImpl(int channel) { return SetLightOnOff(channel, true) ? eLightResult.OK : eLightResult.NG; } #endregion #region fields const byte CR = 0x0D; const byte LF = 0x0A; const byte ACK = 0x06; const byte NAK = 0x15; int _ReceiveSize = 0; string _ValueBuff; #endregion Queue _DataQueue; public Queue GetDataQueue => _DataQueue; private bool SetLightValue(int nChannel, int nValue) { if (!IsSimul) { if (!SerialConn.IsPortOpen()) return false; } //ReceiveStatusMsgAck = false; byte[] bySend = new byte[] { (byte)':', (byte)'1', (byte)'1', (byte)'0', (byte)'0', (byte)'0', (byte)'0', CR, LF }; nValue = Math.Min(Math.Max(nValue, 0), 9999); string strBuf = string.Format("{0:X1}", nChannel + 1); bySend[2] = (byte)strBuf[0]; //string strBuf = string.Format("{0:0000}", nValue); strBuf = string.Format("{0:D4}", nValue); bySend[3] = (byte)strBuf[0]; bySend[4] = (byte)strBuf[1]; bySend[5] = (byte)strBuf[2]; bySend[6] = (byte)strBuf[3]; bool bError = false; try { for (int i = 0; i < 3; i++) { bError = false; _DataQueue.Clear(); SerialConn.Write(bySend); DateTime startTime = DateTime.Now; TimeSpan timeSpan; _ReceiveSize = 0; while (true) { Thread.Sleep(1); DateTime currentTime = DateTime.Now; timeSpan = currentTime - startTime; if (timeSpan.TotalSeconds > 3.0) { bError = true; LOG.D("Receive Msg Timeout"); break; } if (ReadAck()) { break; } } if (bError == false) break; } } catch (UnauthorizedAccessException) { //Console.WriteLine("시리얼 포트에 액세스할 권한이 없습니다."); return false; } catch (System.IO.IOException) { //Console.WriteLine("시리얼 포트를 열 수 없습니다."); return false; } catch (Exception ex) { LOG.W("Warning : " + ex.Message, "SetLightValue"); //Console.WriteLine("오류 발생: " + ex.Message); return false; } return bError ? false : true; } private bool SetLightOnOff(int nChannel, bool bOn) { if (!IsSimul) { if (!SerialConn.IsPortOpen()) return false; } //ReceiveStatusMsgAck = false; byte[] bySend = new byte[] { (byte)':', (byte)'1', (byte)'O', (byte)'0', CR, LF }; string strBuf = string.Format("{0:X}", bOn ? (nChannel + 1) : 0); bySend[3] = (byte)strBuf[0]; bool bError = false; try { for (int i = 0; i < 3; i++) { bError = false; _DataQueue.Clear(); SerialConn.Write(bySend); DateTime startTime = DateTime.Now; TimeSpan timeSpan; while (true) { Thread.Sleep(1); DateTime currentTime = DateTime.Now; timeSpan = currentTime - startTime; if (timeSpan.TotalSeconds > 3.0) { bError = true; LOG.D("Receive Msg Timeout"); break; } if (ReadAck()) { break; } } if (bError == false) break; } } catch (UnauthorizedAccessException) { //Console.WriteLine("시리얼 포트에 액세스할 권한이 없습니다."); return false; } catch (System.IO.IOException) { //Console.WriteLine("시리얼 포트를 열 수 없습니다."); return false; } catch (Exception ex) { LOG.W("Warning : " + ex.Message, "SetLightOnOff"); //Console.WriteLine("오류 발생: " + ex.Message); return false; } return bError ? false : true; } public bool GetLightValue(int nChannel, ref int nValue) { if (!IsSimul) { if (!SerialConn.IsPortOpen()) return false; } //ReceiveStatusMsgValue = false; byte[] bySend = new byte[] { (byte)':', (byte)'R', (byte)'1', CR, LF }; string strBuf = string.Format("{0:X1}", nChannel + 1); bySend[2] = (byte)strBuf[0]; bool bError = false; try { for (int i = 0; i < 3; i++) { bError = false; _DataQueue.Clear(); SerialConn.Write(bySend); DateTime startTime = DateTime.Now; TimeSpan timeSpan; _ReceiveSize = 0; string value = string.Empty; _ValueBuff = string.Empty; while (true) { Thread.Sleep(1); DateTime currentTime = DateTime.Now; timeSpan = currentTime - startTime; if (timeSpan.TotalSeconds > 3.0) { bError = true; LOG.D("Receive Msg Timeout"); break; } if (ReadValue(ref value)) { //nValue = int.Parse(value); int nChNum = 0; int nLightVal = 0; GetChNumAndLightVal(value, ref nChNum, ref nLightVal); nValue = nLightVal; break; } } if (bError == false) break; } } catch (UnauthorizedAccessException) { //Console.WriteLine("시리얼 포트에 액세스할 권한이 없습니다."); return false; } catch (System.IO.IOException) { //Console.WriteLine("시리얼 포트를 열 수 없습니다."); return false; } catch (Exception ex) { LOG.W("Warning : " + ex.Message, "GetLightValue"); //Console.WriteLine("오류 발생: " + ex.Message); return false; } return bError ? false : true; } private void GetChNumAndLightVal(string value, ref int nChNum, ref int nLightVal) { int[] ascii_ch = new int[1]; int[] ascii_value = new int[4]; ascii_ch[0] = int.Parse(value.Substring(5, 2)); ascii_value[0] = int.Parse(value.Substring(13, 2)); ascii_value[1] = int.Parse(value.Substring(15, 2)); ascii_value[2] = int.Parse(value.Substring(17, 2)); ascii_value[3] = int.Parse(value.Substring(19, 2)); char[] cChnum = new char[1]; cChnum[0] = (char)ascii_ch[0]; char[] cLightVal = new char[4]; cLightVal[0] = (char)ascii_value[0]; cLightVal[1] = (char)ascii_value[1]; cLightVal[2] = (char)ascii_value[2]; cLightVal[3] = (char)ascii_value[3]; nChNum = Convert.ToInt32(new string(cChnum)); nChNum -= 1; // ch no은 0-base nLightVal = Convert.ToInt32(new string(cLightVal)); } private bool ReadAck() { byte byReadCommand = new byte(); if (_DataQueue.Count > 0) { byReadCommand = _DataQueue.Dequeue(); _ReceiveSize++; } if ((_ReceiveSize != 0) && byReadCommand == ACK) return true; if (_ReceiveSize >= 1) return true; return false; } private bool ReadValue(ref string value) { if (_DataQueue.Count > 0) { _ValueBuff += _DataQueue.Dequeue(); _ReceiveSize++; } //if (strValueBuff.IndexOf('\n') != -1) if (_ValueBuff.IndexOf((char)LF) != -1) { value = _ValueBuff.Substring(6); return true; } if (_ReceiveSize > 9) { value = _ValueBuff/*.Substring(6)*/; return true; } return false; } private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { //Serial 통신 Read Data #warning [TODO: Aurora 고정부 추가후 수정 필요] int dataLength = (sender as SerialPort).BytesToRead;// _SerialPort.BytesToRead; byte[] byBuffer = new byte[dataLength]; SerialConn.Read(byBuffer); for (int i = 0; i < dataLength; i++) { _DataQueue.Enqueue(byBuffer[i]); } } } }