323 lines
11 KiB
C#
323 lines
11 KiB
C#
/*
|
|
* Copyright (c) 2025 LG Electronics Inc.
|
|
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
|
|
*/
|
|
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using VisionCommon;
|
|
using Hermes;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace VisionLight {
|
|
/// <summary>
|
|
/// 조명 제어 결과
|
|
/// </summary>
|
|
public enum eLightResult {
|
|
/// <summary> 성공 </summary>
|
|
OK,
|
|
/// <summary> 실패 </summary>
|
|
NG,
|
|
/// <summary> 이전 값과 동일할 경우 생략 </summary>
|
|
SKIP
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 베이스 클래스
|
|
/// </summary>
|
|
public abstract class LightBase : Device {
|
|
/// <summary> lock 설정을 위한 객체 </summary>
|
|
protected readonly object LockThis = new object();
|
|
/// <summary> 로그 </summary>
|
|
protected Logger LOG { get; set; }
|
|
|
|
/// <summary>
|
|
/// 채널 별 마지막 조명 값
|
|
/// 마지막 조명 값과 동일한 경우 Write하지 않기 위함.
|
|
/// </summary>
|
|
protected Dictionary<int, int> LastChLevels { get; set; } = new Dictionary<int, int>();
|
|
/// <summary>
|
|
/// 채널 별 마지막 On/Off 상태 값
|
|
/// 마지막 조명 상태와 동일한 경우 Write하지 않기 위함.
|
|
/// </summary>
|
|
protected Dictionary<int, bool> LastChOnOffs { get; set; } = new Dictionary<int, bool>();
|
|
|
|
/// <summary> 디바이스 컨피그 </summary>
|
|
protected LightConfig LightConfig { get; set; }
|
|
/// <summary> 연결 타입 (시리얼 or 소켓) </summary>
|
|
public eLightConnType LightConnType { get; set; } = eLightConnType.None;
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// EquipmentInfo.SimulationMode로 시뮬레이션 상태를 설정한다.
|
|
/// </summary>
|
|
/// <param name="deviceId">디바이스 ID</param>
|
|
protected LightBase(string deviceId)
|
|
: this(deviceId, EquipmentInfoManager.EquipmentInfo.SimulationMode) {
|
|
}
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="deviceId">디바이스 ID</param>
|
|
/// <param name="isSimul">시뮬레이션 상태</param>
|
|
protected LightBase(string deviceId, bool isSimul) {
|
|
IsSimul = isSimul;
|
|
Type = DeviceType.Light;
|
|
DeviceId = deviceId;
|
|
LOG = new Logger(string.Format("{0}[{1}]", GetType().Name, DeviceId)); // Light_XXX[LIGHT#N]
|
|
}
|
|
|
|
/// <summary>
|
|
/// 다비이스 컨피그 설정
|
|
/// </summary>
|
|
/// <param name="lightConfig"></param>
|
|
protected void SetLightConfig(LightConfig lightConfig) {
|
|
LightConfig = lightConfig;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 채널 별 마지막 조명 값, On/Off 상태 설정
|
|
/// </summary>
|
|
protected void InitLastChParams() {
|
|
for (int ch = LightConfig.Channels.Min; ch <= LightConfig.Channels.Max; ch++) {
|
|
if (!LastChOnOffs.ContainsKey(ch)) {
|
|
LastChOnOffs.Add(ch, false);
|
|
}
|
|
}
|
|
for (int ch = LightConfig.Channels.Min; ch <= LightConfig.Channels.Max; ch++) {
|
|
if (!LastChLevels.ContainsKey(ch)) {
|
|
var initLevel = LightConfig.ChannelConfigs.Where(x => x.Ch == ch)?.FirstOrDefault()?.Level ?? 0;
|
|
LastChLevels.Add(ch, initLevel);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 채널 별 마지막 조명 값, On/Off 상태 초기화
|
|
/// </summary>
|
|
protected void ClearLastChParams() {
|
|
LastChOnOffs?.Clear();
|
|
LastChLevels?.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// On 상태 여부 체크
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>true: On, false: Off</returns>
|
|
protected bool IsLastChOn(int channel) {
|
|
if (LastChOnOffs.ContainsKey(channel)) {
|
|
if (LastChOnOffs[channel].Equals(true)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 켜기 수행 메소드
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>실행 결과</returns>
|
|
protected abstract eLightResult SetOnImpl(int channel);
|
|
|
|
/// <summary>
|
|
/// 조명 끄기 수행 메소드
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>실행 결과</returns>
|
|
protected abstract eLightResult SetOffImpl(int channel);
|
|
|
|
/// <summary>
|
|
/// 조명 값 제어 수행 메소드
|
|
/// </summary>
|
|
/// <param name="level">설정 값</param>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>실행 결과</returns>
|
|
protected abstract eLightResult SetLevelImpl(int level, int channel);
|
|
|
|
/// <summary>
|
|
/// 조명 켜기
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <param name="isDefault">Device Actaivated를 무시하고 조명킬지 확인 여부</param>
|
|
/// <returns>조명 제어 결과</returns>
|
|
public eLightResult SetOn(int channel, bool isDefault = false) {
|
|
// 마지막 조명 상태가 On일 경우 그냥 빠져 나감.
|
|
if (!CheckActivated(isDefault) || !CheckChannel(channel)) {
|
|
return eLightResult.NG;
|
|
}
|
|
|
|
if (IsLastChOn(channel)) {
|
|
return eLightResult.SKIP;
|
|
}
|
|
|
|
var res = eLightResult.OK;
|
|
if (!IsSimul) {
|
|
res = SetOnImpl(channel);
|
|
}
|
|
|
|
if (res == eLightResult.OK) {
|
|
LastChOnOffs[channel] = true; // 마지막 조명 상태 저장
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 채널의 조명 켜기
|
|
/// </summary>
|
|
public void SetOnAll() {
|
|
for (int ch = LightConfig.Channels.Min; ch <= LightConfig.Channels.Max; ch++) {
|
|
SetOn(ch);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 채널의 조명 켜기 - Device Activated 여부 무시하고 진행 ( 내부적으로만 사용 )
|
|
/// </summary>
|
|
internal void SetOnAllInternal() {
|
|
for (int ch = LightConfig.Channels.Min; ch <= LightConfig.Channels.Max; ch++) {
|
|
SetOn(ch, isDefault : true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 끄기
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>조명 제어 결과</returns>
|
|
public eLightResult SetOff(int channel) {
|
|
if (!CheckActivated() || !CheckChannel(channel)) {
|
|
return eLightResult.NG;
|
|
}
|
|
// 마지막 조명 상태가 Off일 경우 그냥 빠져 나감.
|
|
if (!IsLastChOn(channel)) {
|
|
return eLightResult.SKIP;
|
|
}
|
|
|
|
var res = eLightResult.OK;
|
|
if (!IsSimul) {
|
|
res = SetOffImpl(channel);
|
|
}
|
|
|
|
if (res == eLightResult.OK) {
|
|
LastChOnOffs[channel] = false; // 마지막 조명 상태 저장
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 채널의 조명 끄기
|
|
/// </summary>
|
|
public void SetOffAll() {
|
|
for (int ch = LightConfig.Channels.Min; ch <= LightConfig.Channels.Max; ch++) {
|
|
SetOff(ch);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 상태 가져오기
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>조명 상태 (on : true, off : false)</returns>
|
|
public bool GetOnOff(int channel) {
|
|
if (!CheckActivated() || !CheckChannel(channel)) {
|
|
return false;
|
|
}
|
|
if (LastChOnOffs.ContainsKey(channel)) {
|
|
return LastChOnOffs[channel];
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 값 가져오기
|
|
/// </summary>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>조명 값</returns>
|
|
public int GetLevel(int channel) {
|
|
if (!CheckActivated() || !CheckChannel(channel)) {
|
|
return -1;
|
|
}
|
|
|
|
if (LastChLevels.ContainsKey(channel)) {
|
|
return LastChLevels[channel];
|
|
}
|
|
|
|
LOG.FuncE($"Invalid channel : {channel}");
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 조명 값 제어 (개별)
|
|
/// </summary>
|
|
/// <param name="level">레벨</param>
|
|
/// <param name="channel">채널 번호</param>
|
|
/// <returns>조명 제어 결과</returns>
|
|
public eLightResult SetLevel(int level, int channel) {
|
|
if (!CheckActivated() || !CheckChannel(channel) || !CheckLevel(level)) {
|
|
return eLightResult.NG;
|
|
}
|
|
|
|
// 마지막 조명값과 동일한 경우 그냥 빠져 나감.
|
|
if (LastChLevels.ContainsKey(channel)) {
|
|
if (LastChLevels[channel].Equals(level)) {
|
|
return eLightResult.SKIP;
|
|
}
|
|
}
|
|
|
|
var res = eLightResult.OK;
|
|
if (!IsSimul) {
|
|
res = SetLevelImpl(level, channel);
|
|
}
|
|
|
|
if (res == eLightResult.OK) {
|
|
LastChLevels[channel] = level; // 마지막 조명 값 저장
|
|
}
|
|
return res;
|
|
}
|
|
|
|
#region Check Method
|
|
/// <summary>
|
|
/// Channel 접근이 정상적인지 확인하는 Method (셋팅값과 동일한지)
|
|
/// </summary>
|
|
/// <param name="channel">채널</param>
|
|
/// <returns>채널 정상 여부</returns>
|
|
internal bool CheckChannel(int channel) {
|
|
if ((LightConfig.Channels.InRange(channel)) || channel == -1) {
|
|
return true;
|
|
}
|
|
else {
|
|
LOG.E($"NotSupported Channel {channel}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// level 접근이 정상적인지 확인하는 Method (Dim Range 셋팅값과 동일한지)
|
|
/// </summary>
|
|
/// <param name="level">조명 값 (Dim Range) </param>
|
|
/// <returns>레벨 정상 여부</returns>
|
|
internal bool CheckLevel(int level) {
|
|
if (LightConfig.DimRange.InRange(level)) {
|
|
return true;
|
|
}
|
|
else {
|
|
LOG.E($"NotSupported level({LightConfig.DimRange.Min} ~ {LightConfig.DimRange.Max}) : {level}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal bool CheckActivated(bool isDiscard = false) {
|
|
if(isDiscard) {
|
|
return true;
|
|
}
|
|
if (!IsActivated) {
|
|
LOG.E($"{DeviceId} : Light Device is not activated");
|
|
}
|
|
return IsActivated;
|
|
}
|
|
#endregion
|
|
}
|
|
} |