/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using System; using System.Collections.Generic; using Hermes; using System.Linq; using System.Text; using System.Threading.Tasks; namespace VisionLight { /// /// !!! 반드시 UDP로 통신할 해야 함 !!! /// [상시 조명 컨트롤러 - 4CH / 소켓 통신] /// Range : (0,255) /// SocketProtocol : TCP or UDP /// IpAddress : XXX.XXX.XXX.XXX /// PortNumber : XXX /// internal class Light_LVS_EN04_Socket : LightBase_Socket { public const byte CMD_START_CODE = 0x01; public const byte CMD_END_CODE = 0x04; public const byte CMD_OP_CODE_WRITE = 0x00; public const byte LENGTH_DATA_MSG = 0x01; public const byte ADDR_SET_LIGHT_ONOFF = 0x34; public const byte ADDR_CHANNEL_SELECT = 0x20; public const byte ADDR_STEP_VALUE = 0x28; public const byte LENGTH_LIGHT_ONOFF_REQUEST_MSG = 6; public const byte LENGTH_SET_CHANNEL_REQUEST_MSG = 6; public const byte LENGTH_SET_LEVEL_REQUEST_MSG = 6; public Light_LVS_EN04_Socket(string deviceId) : base(deviceId) { } protected override eLightResult SetLevelImpl(int level, int channel) { lock (LockThis) { if (ChannelSelect(channel) == E1.OK) { if (SendData_SetLevel(level) == E1.OK) { return eLightResult.OK; } else { return eLightResult.NG; } } else { return eLightResult.NG; } } } private int ChannelSelect(int channel) { try { byte[] sendData = CreateChannelSelectReqMsg(channel); //SerialConn.Write(sendData, sendData.Length); //SocketConn.Send(sendData); SocketConn.SendAndRecieve(sendData, out byte[] receiveData); if (IsRecevieDataACK(receiveData)) { return E1.OK; } } catch (Exception e) { LOG.FuncE(e.Message); } return E1.GENERIC; } private byte[] CreateChannelSelectReqMsg(int channel) { byte[] requestMsg = new byte[LENGTH_SET_CHANNEL_REQUEST_MSG]; requestMsg[0] = CMD_START_CODE; requestMsg[1] = CMD_OP_CODE_WRITE; requestMsg[2] = LENGTH_DATA_MSG; requestMsg[3] = ADDR_CHANNEL_SELECT; requestMsg[4] = (byte)channel; requestMsg[5] = CMD_END_CODE; return requestMsg; } private int SendData_SetLevel(int level) { try { byte[] sendData = CreateSetLevelReqMsg(level); //SerialConn.Write(sendData, sendData.Length); //SocketConn.Send(sendData); SocketConn.SendAndRecieve(sendData, out byte[] receiveData); if (IsRecevieDataACK(receiveData)) { return E1.OK; } } catch (Exception e) { LOG.FuncE(e.Message); } return E1.GENERIC; } private byte[] CreateSetLevelReqMsg(int level) { byte[] requestMsg = new byte[LENGTH_SET_LEVEL_REQUEST_MSG]; requestMsg[0] = CMD_START_CODE; requestMsg[1] = CMD_OP_CODE_WRITE; requestMsg[2] = LENGTH_DATA_MSG; requestMsg[3] = ADDR_STEP_VALUE; requestMsg[4] = (byte)level; requestMsg[5] = CMD_END_CODE; return requestMsg; } protected override eLightResult SetOffImpl(int channel) { lock (LockThis) { if (SendData_SetOnOff(channel) == E1.OK) { return eLightResult.OK; } else { return eLightResult.NG; } } } protected override eLightResult SetOnImpl(int channel) { lock (LockThis) { if (SendData_SetOnOff(channel) == E1.OK) { return eLightResult.OK; } else { return eLightResult.NG; } } } private int SendData_SetOnOff(int channel) { try { byte ChOnOffs = ConvertChOnOffs(channel, LastChOnOffs); byte[] sendData = CreateSetOnOffReqMsg(ChOnOffs); //SerialConn.Write(sendData, sendData.Length); //SocketConn.Send(sendData); SocketConn.SendAndRecieve(sendData, out byte[] receiveData); if (IsRecevieDataACK(receiveData)) { return E1.OK; } } catch (Exception e) { LOG.FuncE(e.Message); } return E1.GENERIC; } private static byte ConvertChOnOffs(int channel, Dictionary lastChOnOffs) { string onOffs = ""; for (int i = 3; i >= 0; i--) { if (i == channel) { lastChOnOffs[i] = !lastChOnOffs[i]; } if (lastChOnOffs.ContainsKey(i)) { if (lastChOnOffs[i].Equals(true)) { onOffs += "1"; } else { onOffs += "0"; } } } return (byte)Convert.ToInt32(onOffs, 2); } private static byte[] CreateSetOnOffReqMsg(byte data) { byte[] requestMsg = new byte[LENGTH_LIGHT_ONOFF_REQUEST_MSG]; requestMsg[0] = CMD_START_CODE; requestMsg[1] = CMD_OP_CODE_WRITE; requestMsg[2] = LENGTH_DATA_MSG; requestMsg[3] = ADDR_SET_LIGHT_ONOFF; requestMsg[4] = data; requestMsg[5] = CMD_END_CODE; return requestMsg; } private bool IsRecevieDataACK(byte[] receiveData) { if (receiveData == null) { LOG.FuncE("ReceiveData is null."); return false; } else if (receiveData.Length == 0) { LOG.FuncE("ReceiveData Length Zero."); return false; } else if (receiveData[0] == 0x15) { LOG.FuncE("ReceiveData NAK Error."); return false; } else { return true; // 0x06 : ACK } } } }