using Aurora.Api.DataType; using Aurora.Api.Devices; using Hermes; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AuroraLight.LvsPn { internal class LvsPnLight : SerialConn, ILvsPnLight { public const byte CMD_SINGLE_CHANNEL_OFF = 0x45; // E public const byte CMD_SINGLE_CHANNEL_BRIGHTNESS = 0x4C; // L public const byte CMD_ALL_CHANNEL_BRIGHTNESS = 0x41; // A public const byte CMD_VALUE_SEPARATOR = 0x2C; // , public const byte BYTE_ACK = 0x06; // 06 public const byte BYTE_NAK = 0x15; // 21 public const byte BYTE_CR = 0x0D; // 13 public const byte BYTE_LF = 0x0A; // 10 public const byte BYTE_0 = 0x30; // 48 public const byte LENGTH_SINGLE_CHANNEL_OFF_REQUEST_MSG = 4; public const byte LENGTH_SINGLE_CHANNEL_BRIGHTNESS_REQUEST_MSG = 7; public const byte LENGTH_ALL_CHANNEL_BRIGHTNESS_REQUEST_MSG = 18; public const byte LENGTH_RESPONSE_MSG = 1; public const int MAX_BRIGHTNESS = 255; protected readonly object LockThis; LvsPnLightConfig _config; private string _deviceId; public bool _commError { get; set; } = false; public LvsPnLight(string deviceId, bool isSimul, LightConfig config) : base(deviceId, isSimul) { if (config is LvsPnLightConfig) { _config = config as LvsPnLightConfig; } else { Log.E("Config Type Error!"); throw new NotImplementedException(); } LightValue = Enumerable.Repeat(0, 4).ToArray(); _deviceId = deviceId; } public int[] LightValue { get; set; } /// /// Initialize AllOffLight() and LightValue initialize /// /// public bool InitInternal(SerialConnConfig conn) { LightValue = Enumerable.Repeat(0, 4).ToArray(); bool bRet = false; bRet = Open(conn) == E1.OK; if (bRet) { bRet = OffLightInternal() == E1.OK; if (bRet) Log.D(string.Format("[ {0} CONNECTED ]", _deviceId)); _commError = !bRet; } else { _commError = true; } return bRet; } public int GetMaxValueInternal() { return MAX_BRIGHTNESS; } public bool IsPortErrorInternal() { return _commError; } /// /// All Channel Light off /// /// public int OffLightInternal() { lock (LockThis) { var denormalValues = Enumerable.Repeat(0, 4).ToList(); byte[] requestMsg = CreateAllChannelBrightnessReqMsg(denormalValues); if (Write(requestMsg)) { byte[] responseMsg = new byte[LENGTH_RESPONSE_MSG]; if (Read(responseMsg) <= 0) { Log.E("ReadError"); return E2.INTERNAL_ERROR; } var isValid = ValidateResponse(responseMsg); if (!isValid) { Log.E("NAK"); return E2.INTERNAL_ERROR; } LightValueSet(0); } } return E1.OK; } public int OffLightInternal(int iChannel) { if (!IsValidChannel(iChannel)) { Log.E(string.Format("Argument Error! Ch : {0}", iChannel.ToString())); return E2.INVALID_ARGUMENT; } lock (LockThis) { byte[] requestMsg = CreateSingleChannelOffReqMsg(iChannel); if (Write(requestMsg)) { byte[] responseMsg = new byte[LENGTH_RESPONSE_MSG]; if (Read(responseMsg) <= 0) { Log.E("ReadError"); return E2.INTERNAL_ERROR; } var isValid = ValidateResponse(responseMsg); if (!isValid) { Log.E("NAK"); return E2.INTERNAL_ERROR; } LightValueSet(iChannel, 0); } } return E1.OK; } public int SetLightValueInternal(List values) { if (values.Count != 4) { return E2.INVALID_ARGUMENT; } var denormalValues = DenormailzeBrightness(values); for (int i = 0; i < denormalValues.Count; i++) { if (!IsValidBrightness(denormalValues[i])) { Log.E(string.Format("Argument Error! Ch : {0}, Value : {1}({2})", (i + 1), values[i], denormalValues[i])); return E2.INVALID_ARGUMENT; } } lock (LockThis) { byte[] requestMsg = CreateAllChannelBrightnessReqMsg(denormalValues); if (Write(requestMsg)) { byte[] responseMsg = new byte[LENGTH_RESPONSE_MSG]; if (Read(responseMsg) <= 0) { Log.E("ReadError"); return E2.INTERNAL_ERROR; } var isValid = ValidateResponse(responseMsg); if (!isValid) { Log.E("NAK"); return E2.INTERNAL_ERROR; } LightValueSet(values); } } return E1.OK; } public int SetLightValueInternal(int iChannel, int iValue) { var denormalValue = DenormailzeBrightness(iValue); if (!IsValidChannel(iChannel) || !IsValidBrightness(denormalValue)) { Log.E(string.Format("Argument Error! Ch : {0}, Value : {1}({2})", iChannel, iValue, denormalValue)); return E2.INVALID_ARGUMENT; } lock (LockThis) { byte[] requestMsg = CreateSingleChannelBrightnessReqMsg(iChannel, denormalValue); if (Write(requestMsg)) { byte[] responseMsg = new byte[LENGTH_RESPONSE_MSG]; if (Read(responseMsg) <= 0) { Log.E("ReadError"); return E2.INTERNAL_ERROR; } var isValid = ValidateResponse(responseMsg); if (!isValid) { Log.E("NAK"); return E2.INTERNAL_ERROR; } LightValueSet(iChannel, iValue); } } return E1.OK; } #region UtilLvsPnLight private void LightValueSet(int iChannel, int iValue) { LightValue[iChannel] = iValue; } private void LightValueSet(int iValue) { for (int i = 0; i < 4; i++) { LightValue[i] = iValue; } } private void LightValueSet(List iValues) { for (int i = 0; i < 4; i++) { LightValue[i] = iValues[i]; } } private bool IsValidChannel(int iChannel) { return 1 <= iChannel && iChannel <= 4; } private bool IsValidBrightness(int iValue) { return 0 <= iValue && iValue <= 255; } private byte[] CreateSingleChannelBrightnessReqMsg(int iChannel, int iValue) { byte[] requestMsg = new byte[LENGTH_SINGLE_CHANNEL_BRIGHTNESS_REQUEST_MSG]; byte[] valueByte = ConvertBrightnessIntToBytes(iValue); requestMsg[0] = CMD_SINGLE_CHANNEL_BRIGHTNESS; requestMsg[1] = ConvertChannelIntToByte(iChannel); Array.Copy(valueByte, 0, requestMsg, 2, valueByte.Length); requestMsg[requestMsg.Length - 2] = BYTE_CR; requestMsg[requestMsg.Length - 1] = BYTE_LF; return requestMsg; } private byte ConvertChannelIntToByte(int iChannel) { return (byte)(iChannel + BYTE_0); } private byte[] ConvertBrightnessIntToBytes(int iValue) { return Encoding.Default.GetBytes(ConvertBrightnessIntToString(iValue)); } private string ConvertBrightnessIntToString(int iValue) { return string.Format("{0:000}", iValue); } private bool ValidateResponse(byte[] msg) { return msg[0] == BYTE_ACK; } private byte[] CreateAllChannelBrightnessReqMsg(List values) { byte[] requestMsg = new byte[LENGTH_ALL_CHANNEL_BRIGHTNESS_REQUEST_MSG]; byte[] valueByte = ConvertBrightnessIntToBytes(values); requestMsg[0] = CMD_ALL_CHANNEL_BRIGHTNESS; Array.Copy(valueByte, 0, requestMsg, 1, valueByte.Length); requestMsg[requestMsg.Length - 2] = BYTE_CR; requestMsg[requestMsg.Length - 1] = BYTE_LF; return requestMsg; } private byte[] ConvertBrightnessIntToBytes(List values) { string valueStr = string.Format("{0},{1},{2},{3}", ConvertBrightnessIntToString(values[0]), ConvertBrightnessIntToString(values[1]), ConvertBrightnessIntToString(values[2]), ConvertBrightnessIntToString(values[3])); return Encoding.Default.GetBytes(valueStr); } private byte[] CreateSingleChannelOffReqMsg(int iChannel) { byte[] requestMsg = new byte[LENGTH_SINGLE_CHANNEL_OFF_REQUEST_MSG]; requestMsg[0] = CMD_SINGLE_CHANNEL_OFF; requestMsg[1] = ConvertChannelIntToByte(iChannel); requestMsg[requestMsg.Length - 2] = BYTE_CR; requestMsg[requestMsg.Length - 1] = BYTE_LF; return requestMsg; } private List DenormailzeBrightness(List values) { if (_config.UseNormalizedBrightness) { var normalizedValues = new List(); foreach (var value in values) { normalizedValues.Add(DenormailzeBrightness(value)); } return normalizedValues; } return new List(values); } private int DenormailzeBrightness(int brightness) { if (_config.UseNormalizedBrightness) { var maxNormal = 100.0; var maxDenormal = GetMaxValueInternal(); return Convert.ToInt32(Math.Round(brightness * maxDenormal / maxNormal)); } return brightness; } #endregion } }