2026-06-05 13:44:39 +09:00

213 lines
7.3 KiB
C#

using Aurora.Api.Devices;
using Hermes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AuroraLight.IF
{
internal class IFLight : SerialConn, IIFLight
{
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 IFLight(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<int>();
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<int> 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);
}
}
/// <summary>
/// 조명의 채널을 키고 끄는 함수(밝기 값은 유지됨)
/// </summary>
/// <param name="channel">설정할 조명 채널(0부터 시작)</param>
/// <param name="on">ON/OFF</param>
public void SetLightPowerStatus(int channel, bool bOn)
{
try {
if (!IsConnected())
return;
else if (channel < 0 || _lightChannelCount - 1 < channel)
return;
lock (this) {
byte[] command = new byte[6];
char channelChar = (channel + 1).ToString()[0];
string value = String.Empty;
if (bOn) {
value = String.Format("{0:D}ON", channel + 1); // 1ON, 2ON
} else {
value = "OFF";
}
byte[] data = Encoding.UTF8.GetBytes(value);
command[0] = 0x02;
command[1] = Convert.ToByte(channelChar); // CH1 -> 1, CH2 -> 2
command[2] = data[0];
command[3] = data[1];
command[4] = data[2];
command[5] = 0x03;
Write(command);
}
} catch (Exception e) {
Log.W($"{channel}ch SetLightPowerStatus Failed. ( {e.Message} )");
}
}
public int SetLightBrightness(int channel, int brightnessValue)
{
// <param> brightnessValue : (0~255)
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;
lock (this) {
byte[] command = new byte[6];
char channelChar = (channel + 1).ToString()[0];
string value = brightnessValue.ToString("D3");
command[0] = 0x02;
command[1] = Convert.ToByte(channelChar); // CH1 -> 1, CH2 -> 2
command[2] = Convert.ToByte(value[0]);
command[3] = Convert.ToByte(value[1]);
command[4] = Convert.ToByte(value[2]);
command[5] = 0x03;
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 <= 255 && iValue >= 0) {
return true;
} else {
Log.W($"LightValue Range Error. Range : 0~255, Input : {iValue}");
return false;
}
}
}
}