291 lines
9.0 KiB
C#
291 lines
9.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO.Ports;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Aurora.Api;
|
||
using Aurora.Api.Devices;
|
||
using Hermes;
|
||
|
||
namespace AuroraChiller
|
||
{
|
||
public class DongShinChiller : DongShinChillerBase {
|
||
public const string OP_GET = "01";
|
||
public const int OP_GET_COOLING_STATUS = 1;
|
||
public const int OP_GET_TARGET_TEMP = 2;
|
||
public const int OP_GET_LOW_TEMP1 = 3;
|
||
public const int OP_GET_LOW_TEMP2 = 4;
|
||
public const int OP_GET_HIGH_TEMP1 = 5;
|
||
public const int OP_GET_HIGH_TEMP2 = 6;
|
||
public const int OP_GET_CURRENT_TEMP = 7;
|
||
public const int OP_GET_ERROR = 8;
|
||
|
||
public const string OP_SET_COOLING_STATUS = "11";
|
||
public const string OP_SET_TARGET_TEMP = "12";
|
||
public const string OP_SET_LOW_TEMP1 = "13";
|
||
public const string OP_SET_LOW_TEMP2 = "14";
|
||
public const string OP_SET_HIGH_TEMP1 = "15";
|
||
public const string OP_SET_HIGH_TEMP2 = "16";
|
||
|
||
public const byte BYTE_STX = 0x02; // 02
|
||
public const byte BYTE_CR = 0x0D; // 13
|
||
public const byte BYTE_0 = 0x30; // 48
|
||
public const byte BYTE_1 = 0x31; // 49
|
||
public const byte BYTE_5 = 0x35; // 53
|
||
|
||
private Config _Config;
|
||
|
||
public DongShinChiller(string deviceId) : base(deviceId) {
|
||
}
|
||
|
||
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() {
|
||
// Set init vaues from config
|
||
return E1.OK;
|
||
}
|
||
|
||
protected override int DoDeactivate() {
|
||
return Close();
|
||
}
|
||
|
||
#region Set
|
||
public override bool SetCooling(bool bOn) {
|
||
return SetValue(OP_SET_COOLING_STATUS, bOn);
|
||
}
|
||
|
||
public override bool SetTargetTemp(double temp) {
|
||
return SetValue(OP_SET_TARGET_TEMP, temp);
|
||
}
|
||
|
||
public override bool SetLowTemp1(double temp) {
|
||
return SetValue(OP_SET_LOW_TEMP1, temp);
|
||
}
|
||
|
||
public override bool SetLowTemp2(double temp) {
|
||
return SetValue(OP_SET_LOW_TEMP2, temp);
|
||
}
|
||
|
||
public override bool SetHighTemp1(double temp) {
|
||
return SetValue(OP_SET_HIGH_TEMP1, temp);
|
||
}
|
||
|
||
public override bool SetHighTemp2(double temp) {
|
||
return SetValue(OP_SET_HIGH_TEMP2, temp);
|
||
}
|
||
|
||
private bool SetValue(string cmd, double value) {
|
||
if (!IsPortOpen()) {
|
||
return false;
|
||
}
|
||
|
||
lock (LockThis) {
|
||
|
||
}
|
||
byte[] opCode = Encoding.Default.GetBytes(cmd);
|
||
|
||
if (opCode[0] != '1' || opCode[1] < '2' || '6' < opCode[1]) {
|
||
return false;
|
||
}
|
||
|
||
// Data Format : ab.c
|
||
var dataByte = Encoding.Default.GetBytes(
|
||
string.Format("{0:00.0}", Math.Abs(value)));
|
||
|
||
byte[] sendData = new byte[10];
|
||
sendData[0] = BYTE_STX;
|
||
sendData[1] = opCode[0]; // ‘12’ ~ '16'
|
||
sendData[2] = opCode[1];
|
||
sendData[3] = BYTE_5; //Data Length (1byte)
|
||
sendData[4] = (value < 0) ? Convert.ToByte('-') : Convert.ToByte('+');
|
||
sendData[5] = dataByte[0]; // Data a
|
||
sendData[6] = dataByte[1]; // Data b
|
||
sendData[7] = dataByte[2]; // Data .
|
||
sendData[8] = dataByte[3]; // Data c
|
||
sendData[9] = BYTE_CR;
|
||
|
||
return Write(sendData);
|
||
}
|
||
|
||
private bool SetValue(string cmd, bool value) {
|
||
if (!IsPortOpen()) {
|
||
return false;
|
||
}
|
||
|
||
lock (LockThis) {
|
||
if (cmd != OP_SET_COOLING_STATUS) {
|
||
return false;
|
||
}
|
||
|
||
byte[] sendData = new byte[6];
|
||
byte[] opCode = Encoding.Default.GetBytes(cmd);
|
||
|
||
sendData[0] = BYTE_STX;
|
||
sendData[1] = opCode[0]; //‘11’
|
||
sendData[2] = opCode[1];
|
||
sendData[3] = BYTE_1; //Data Length (1byte)
|
||
sendData[4] = (value) ? BYTE_1 : BYTE_0;
|
||
sendData[5] = BYTE_CR;
|
||
|
||
return Write(sendData);
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region Get
|
||
public override int GetCoolingOnStatus() {
|
||
return GetValueInt(OP_GET, OP_GET_COOLING_STATUS);
|
||
}
|
||
|
||
public override double GetTargetTemp() {
|
||
return GetValueDouble(OP_GET, OP_GET_TARGET_TEMP);
|
||
}
|
||
|
||
public override double GetLowTemp1() {
|
||
return GetValueDouble(OP_GET, OP_GET_LOW_TEMP1);
|
||
}
|
||
|
||
public override double GetLowTemp2() {
|
||
return GetValueDouble(OP_GET, OP_GET_LOW_TEMP2);
|
||
}
|
||
|
||
public override double GetHighTemp1() {
|
||
return GetValueDouble(OP_GET, OP_GET_HIGH_TEMP1);
|
||
}
|
||
|
||
public override double GetHighTemp2() {
|
||
return GetValueDouble(OP_GET, OP_GET_HIGH_TEMP2);
|
||
}
|
||
|
||
public override double GetCurrentTemp() {
|
||
return GetValueDouble(OP_GET, OP_GET_CURRENT_TEMP);
|
||
}
|
||
|
||
public override int GetError() {
|
||
return GetValueInt(OP_GET, OP_GET_ERROR);
|
||
}
|
||
|
||
private int GetValueInt(string cmd, int code) {
|
||
var strReceive = GetValueString(cmd, code);
|
||
|
||
if (CheckNumberString(strReceive)) {
|
||
return Convert.ToInt32(strReceive);
|
||
}
|
||
return E1.GENERIC;
|
||
}
|
||
|
||
private double GetValueDouble(string cmd, int code) {
|
||
var strReceive = GetValueString(cmd, code);
|
||
|
||
if (CheckNumberString(strReceive)) {
|
||
return Convert.ToDouble(strReceive);
|
||
}
|
||
return E1.GENERIC;
|
||
}
|
||
|
||
private string GetValueString(string cmd, int value) {
|
||
if (!IsPortOpen()) {
|
||
return string.Empty;
|
||
}
|
||
|
||
lock (LockThis) {
|
||
if (cmd != OP_GET) {
|
||
return string.Empty;
|
||
}
|
||
|
||
byte[] sendData = new byte[6];
|
||
byte[] opCode = Encoding.Default.GetBytes(cmd);
|
||
|
||
sendData[0] = BYTE_STX;
|
||
sendData[1] = opCode[0]; //‘01’
|
||
sendData[2] = opCode[1];
|
||
sendData[3] = BYTE_1; //Data Length (1byte)
|
||
sendData[4] = (byte)(BYTE_0 + value);
|
||
sendData[5] = BYTE_CR;
|
||
|
||
#warning 읽는 방식 바꿀것. 사용한 적 없는 디바이스.
|
||
string readData = string.Empty;
|
||
//if (!ReadExisting(sendData, out readData)) {
|
||
// return string.Empty;
|
||
//}
|
||
|
||
return readData;
|
||
}
|
||
}
|
||
|
||
private bool CheckNumberString(string str) {
|
||
if (str == string.Empty) {
|
||
return false;
|
||
}
|
||
|
||
var numBytes = Encoding.Default.GetBytes(str);
|
||
int index = 0;
|
||
|
||
// 양수 및 음수(+/-) 부호 체크
|
||
if (numBytes[index] == '-' || numBytes[index] == '+') {
|
||
index++;
|
||
}
|
||
|
||
// 문자열 앞에 0이 있을 경우 0.123 형태의 소수점 숫자인지 잘못된 숫자인지 체크
|
||
if (numBytes[index] == BYTE_0) {
|
||
if (numBytes.Length == 1) {
|
||
return true;
|
||
}
|
||
|
||
index++;
|
||
if (numBytes[index] != '.' && !IsDigit(numBytes[index])) {
|
||
return false;
|
||
}
|
||
index++;
|
||
}
|
||
|
||
// 입력받은 문자열 중간에 숫자가 아닌 문자 존재여부 판별 및 올바른 형태의 숫자여부 판별
|
||
int pointCount = 0;
|
||
int lengthCount = 0;
|
||
while (index < numBytes.Length) {
|
||
// 소수점 체크. 소수점은 1.234처럼 숫자 중간에 단 한개만 올 수 있으며,
|
||
// .123과 같이 숫자 맨 앞에 혹은 123. 과 같이 숫자 맨 뒤에 소수점이 올 수 없다.
|
||
if (!IsDigit(numBytes[index])) {
|
||
if ((numBytes[index] != '.') ||
|
||
(numBytes[index] == '.' && lengthCount == 0) ||
|
||
(numBytes[index] == '.' && pointCount > 0)) {
|
||
return false;
|
||
}
|
||
else {
|
||
index++;
|
||
if (index >= numBytes.Length) {
|
||
return false;
|
||
}
|
||
pointCount++;
|
||
}
|
||
}
|
||
else {
|
||
index++;
|
||
}
|
||
lengthCount++;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private bool IsDigit(byte b) {
|
||
return ('0' <= b && b <= '9');
|
||
}
|
||
#endregion
|
||
}
|
||
}
|