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

307 lines
9.4 KiB
C#

using Aurora.Api;
using Aurora.Api.DataType;
using Aurora.Api.Devices;
using Hermes;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
namespace AuroraLight.LvsPn
{
public class LvsPnLightDevice : SerialPortDevice
{
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;
private Config _Config;
public LvsPnLightDevice(string deviceId, bool isSimul = false) : base(deviceId, isSimul)
{
}
protected override int DoActivate(IDeviceConfig config)
{
_Config = config as Config;
if (IsPortOpen()) {
return E1.OK;
}
var result = Open(_Config.ConnConfig as SerialConnConfig);
if (result == E1.OK) {
return Init();
}
return result;
}
private int Init()
{
return E1.OK;
}
protected override int DoDeactivate()
{
return Close();
}
public int GetMaxValue()
{
return MAX_BRIGHTNESS;
}
public bool SetLightValue(int iChannel, int iValue)
{
if (IsSimul)
return true;
if (!IsActivated)
return false;
var denormalValue = DenormailzeBrightness(iValue);
if (!IsValidChannel(iChannel) || !IsValidBrightness(denormalValue)) {
Log.E(string.Format("Argument Error! Ch : {0}, Value : {1}({2})", iChannel, iValue, denormalValue));
return false;
}
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 false;
}
var isValid = ValidateResponse(responseMsg);
if (!isValid) {
Log.E("NAK");
return false;
}
}
}
return true;
}
private static bool IsValidChannel(int iChannel)
{
return 1 <= iChannel && iChannel <= 4;
}
private static bool IsValidBrightness(int iValue)
{
return 0 <= iValue && iValue <= 255;
}
private static 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 static byte ConvertChannelIntToByte(int iChannel)
{
return (byte)(iChannel + BYTE_0);
}
private static byte[] ConvertBrightnessIntToBytes(int iValue)
{
return Encoding.Default.GetBytes(ConvertBrightnessIntToString(iValue));
}
private static string ConvertBrightnessIntToString(int iValue)
{
return string.Format("{0:000}", iValue);
}
private static bool ValidateResponse(byte[] msg)
{
return msg[0] == BYTE_ACK;
}
public bool SetLightValue(List<int> values)
{
if (IsSimul)
return true;
if (!IsActivated)
return false;
if (values.Count != 4) {
return false;
}
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 false;
}
}
lock (LockThis) {
byte[] requestMsg = CreateAllChannelBrightnessReqMsg(denormalValues);
if (Write(requestMsg)) {
byte[] responseMsg = new byte[LENGTH_RESPONSE_MSG];
if (Read(responseMsg) <= 0) {
Log.E("ReadError");
return false;
}
var isValid = ValidateResponse(responseMsg);
if (!isValid) {
Log.E("NAK");
return false;
}
}
}
return true;
}
private static byte[] CreateAllChannelBrightnessReqMsg(List<int> 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 static byte[] ConvertBrightnessIntToBytes(List<int> 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);
}
public bool OffLight(int iChannel)
{
if (IsSimul)
return true;
if (!IsActivated)
return false;
if (!IsValidChannel(iChannel)) {
Log.E(string.Format("Argument Error! Ch : {0}", iChannel.ToString()));
return false;
}
lock (LockThis) {
byte[] requestMsg = CreateSingleChannelOffReqMsg(iChannel);
if (Write(requestMsg)) {
byte[] responseMsg = new byte[LENGTH_RESPONSE_MSG];
if (Read(responseMsg) <= 0) {
Log.E("ReadError");
return false;
}
var isValid = ValidateResponse(responseMsg);
if (!isValid) {
Log.E("NAK");
return false;
}
}
}
return true;
}
private static 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<int> DenormailzeBrightness(List<int> values)
{
if (_Config.UseNormalizedBrightness) {
var normalizedValues = new List<int>();
foreach (var value in values) {
normalizedValues.Add(DenormailzeBrightness(value));
}
return normalizedValues;
}
return new List<int>(values);
}
private int DenormailzeBrightness(int brightness)
{
if (_Config.UseNormalizedBrightness) {
var maxNormal = 100.0;
var maxDenormal = GetMaxValue();
return Convert.ToInt32(Math.Round(brightness * maxDenormal / maxNormal));
}
return brightness;
}
public class Config : IDeviceConfig
{
public IConnConfig ConnConfig { get; set; }
public bool UseNormalizedBrightness { get; set; } = true;
public Config()
{
ConnConfig = new SerialConnConfig() {
BaudRate = 9600,
DataBits = 8,
StopBits = StopBits.One,
Parity = Parity.None,
PortNum = 1
};
}
public static Config GetDefaultConfig()
{
return new Config();
}
}
}
}