using Aurora.Api.Devices; using Hermes; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AuroraLight.Fainstec { internal class PNLight : SerialConn, IPNLight { private string _deviceId; private int _lightChannelCount; public bool _commError { get; set; } = false; private SerialConnConfig _connConfig; readonly int BYTE_MAX = 1024; public int[] LightValue { get; set; } const int LIGHT_MAX_VALUE = 255; protected int m_timeOut = 1; public PNLight(string deviceId, bool isSimul, int lightChannelCount) : base(deviceId, isSimul) { _deviceId = deviceId; _lightChannelCount = lightChannelCount; LightValue = new int[lightChannelCount]; } public bool InitInternal(SerialConnConfig conn) { _connConfig = conn; LightValue = Enumerable.Repeat(0, (int)_lightChannelCount).ToArray(); bool bRet = false; try { // Legacy 에는 Buffer clear 를 위한 Reset 함수가 있으나, Aurora SerialConn 에서는 Write 할때 Buffer clear 를 자동으로 해준다. // Open 할때 자동으로 켜줄것인가? 켜는함수는 따로 호출할것인가. Legacy 에서는 자동으로 켜줬는데 다른 Device 는 자동으로 켜주지 않는다. bRet = Open(_connConfig) == E1.OK; if (bRet) { bRet = OffLightInternal() == E1.OK; if (bRet) Log.D(string.Format("[ {0} CONNECTED ]", _deviceId)); _commError = !bRet; } else { _commError = true; } return bRet; } catch (Exception e) { Log.W($"InitInternal Failed. ( {e.Message} )"); return bRet; } } public bool IsPortErrorInternal() { return _commError; } public int OffLightInternal() { try { if (!IsConnected()) return E2.NOT_CONNECTED; SetAllLightPowerStatus(false); return E1.OK; } catch (Exception e) { Log.W($"OffLightInternal Failed. ( {e.Message} )"); return E2.CANCELLED; } } public int OffLightInternal(int iChannel) { try { if (!IsConnected()) return E2.NOT_CONNECTED; SetLightPowerStatus(iChannel, false); return E1.OK; } catch (Exception e) { Log.W($"{iChannel}ch OffLightInternal Failed. ( {e.Message} )"); return E2.CANCELLED; } } public int SetLightValueInternal(List values) { try { bool bRet = true; for (int i = 0; i < values.Count; i++) { if (SetLightBrightness(i, values[i]) != E1.OK) bRet = false; } return bRet ? E1.OK : E2.CANCELLED; } catch (Exception e) { Log.W($"SetLightValueInternal Failed. ( {e.Message} )"); return E2.CANCELLED; } } public int SetLightValueInternal(int iChannel, int iValue) { try { return SetLightBrightness(iChannel, iValue); } catch (Exception e) { Log.W($"{iChannel}ch SetLightValueInternal Failed. ( {e.Message} )"); return E2.CANCELLED; } } public void SetAllLightPowerStatus(bool on) { for (int i = 0; i < _lightChannelCount; i++) { SetLightPowerStatus(i, on); } } /// /// 조명의 채널을 키고 끄는 함수(밝기 값은 유지됨) /// /// 설정할 조명 채널(0부터 시작) /// ON/OFF public void SetLightPowerStatus(int channel, bool bOn) { try { if (!IsConnected()) return; else if (channel < 0 || _lightChannelCount - 1 < channel) return; if (bOn == false) { // 조명 컨트롤러 OFF 설정 byte[] command = new byte[4]; command[0] = 0x45; //선두문자 command[1] = Encoding.ASCII.GetBytes(Convert.ToString(channel + 1))[0]; ; //Channel 번호 command[2] = 0x0D;// CR command[3] = 0x0A;// LF Write(command); } else { //CAUTION: 조명 컨트롤러에서 별도로 ON하는 기능은 없고, 밝기값으로 설정해야 함. SetLightBrightness(channel, LightValue[channel]); } } catch (Exception e) { Log.W($"{channel}ch SetLightPowerStatus Failed. ( {e.Message} )"); } } public int SetLightBrightness(int channel, int brightnessValue) { // brightnessValue : (0~100) uint targetLightValue = (uint)(LIGHT_MAX_VALUE * (brightnessValue * 0.01)); try { if (!IsConnected()) return E2.NOT_CONNECTED; if (!ChannelValidCheck(channel)) return E2.INVALID_ARGUMENT; if (!ValueValidCheck(brightnessValue)) return E2.INVALID_ARGUMENT; //ON/OFF 설정 byte[] command = new byte[7]; command[0] = 0x4C; //선두문자 command[1] = Encoding.ASCII.GetBytes(Convert.ToString(channel + 1))[0]; ; //Channel 번호 byte[] value = Encoding.ASCII.GetBytes(string.Format("{0:D3}", targetLightValue)); Array.Copy(value, 0, command, 2, value.Length); command[5] = 0x0D;// CR command[6] = 0x0A;// LF if (Write(command)) { LightValue[channel] = brightnessValue; return E1.OK; } else { return E2.CANCELLED; } } catch (Exception e) { Log.W($"{channel}ch SetLightBrightness Failed. ( {e.Message} )"); return E2.CANCELLED; } } private bool ChannelValidCheck(int iChannel) { if (iChannel < _lightChannelCount && iChannel >= 0) { return true; } else { Log.W($"Channel is not exist. Range : 0~{(int)_lightChannelCount - 1} Input : {iChannel}"); return false; } } private bool ValueValidCheck(int iValue) { if (iValue <= 100 && iValue >= 0) { return true; } else { Log.W($"LightValue Range Error. Range : 0~255, Input : {iValue}"); return false; } } } }