RefrigeratorController.cs 9.9 KB
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OnlineStore
{
    public class RefrigeratorController
    {
        private static int bautRate = 9600;//波特率
        private static Parity parity = Parity.None;//校验位
        private static int dataBits = 8;//数据位
        private static StopBits stopBits = StopBits.One; //停止位
        private static Dictionary<string, AcSerialBean> SerialMap = new Dictionary<string, AcSerialBean>();
        private static string LogName = "";
        
        private static AcSerialBean GetSerialBean(string port)
        {
            if (SerialMap.ContainsKey(port))
            {
                return SerialMap[port];
            }
            return null;
        }
        public static void OpenAll(string[] ports)
        {
            foreach (string port in ports)
            {
                Init(port);
            }
        }
        public static bool Init(string port)
        {
            if (SerialMap.ContainsKey(port))
            {
                return true;
            }
            LogName = "制冷机[" + port + "]";

            AcSerialBean sb = new AcSerialBean(port, bautRate, parity, dataBits, stopBits);

            try
            {
                if (sb.openPort())
                {
                    if (SerialMap.ContainsKey(port))
                    {
                        SerialMap.Remove(port);
                    }
                    SerialMap.Add(port, sb);
                    return true;
                }
                else
                {
                    LogUtil.error(LogName + "串口打开失败!");
                    return false;
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(LogName + " 打开串口出错:" + ex.ToString());
            }
            return true;
        }

        public static bool IsRun(string port)
        {
            if (GetSerialBean(port) != null)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 释放资源
        /// </summary>
        public static void Release(params string[] ports)
        {
            if (ports.Length <= 0)
            {
                ports = (new List<string>(SerialMap.Keys)).ToArray();
            }
            foreach (string port in ports)
            {
                try
                {
                    AcSerialBean sb = GetSerialBean(port);
                    if (sb != null)
                    {
                        sb.closePort();
                    }
                    //IsRun = false;
                    SerialMap.Remove(port);
                }
                catch (Exception ex)
                {
                    LogUtil.error("Release Humiture port [" + port + "] error :" + ex.ToString());
                }
            }
        }

        /// <summary>
        /// 返回温度和湿度
        /// </summary>
        /// <returns></returns>
        public static double queryData(string port,out string state,out string als,out string sls)
        {

            Dictionary<uint, string> AlertState = new Dictionary<uint, string>();
            AlertState.Add(0b10000000, "压力开关报警");
            AlertState.Add(0b01000000, "紧急外部报警");
            AlertState.Add(0b00100000, "普通外部报警");
            AlertState.Add(0b00010000, "超出试用时间报警");
            AlertState.Add(0b00001000, "库温超下限报警");
            AlertState.Add(0b00000100, "库温超上限报警");
            AlertState.Add(0b00000010, "化霜探头故障报警");
            AlertState.Add(0b00000001, "库温探头故障报警");
            Dictionary<uint, string> RunState = new Dictionary<uint, string>();
            RunState.Add(0b10000000, "保留");
            RunState.Add(0b01000000, "保留");
            RunState.Add(0b00100000, "保留");
            RunState.Add(0b00010000, "制冷或制热状态");
            RunState.Add(0b00001000, "风机状态");
            RunState.Add(0b00000100, "制热开机状态");
            RunState.Add(0b00000010, "制冷开机状态");
            RunState.Add(0b00000001, "化霜状态");

            state = "";
            als = "";
            sls = "";

            AcSerialBean sb = GetSerialBean(port);
            if (sb == null)
            {
                return -1;
            }
            byte[] sendData = new byte[7];
            sendData[0] = 0x01;
            sendData[1] = 0x42;
            sendData[2] = 0x09;
            sendData[3] = 0x00;
            sendData[4] = 0x00;
            sendData[5] = 0x00;
            sendData[6] = 0x00;
            sendData = buildCheckData(sendData, sendData.Length - 2);
            string str = AcSerialBean.byteToHexStr(sendData);
            LogUtil.debug("制冷控制器发送:" + str);
            byte[] reviceData = new byte[23];
            bool isOk = false;
            sb.SendCommand(sendData, ref reviceData, 100, out isOk);
            LogUtil.debug("制冷控制器接收:" + AcSerialBean.byteToHexStr(reviceData,""));

            var b = reviceData;
            double temp = -1;
            var ss = "";
            if (b[0] != 0x01 || b[1] != 0x42 || b[2] != 0x09)
            {
                ss += "通讯错误";
            }
            else
            {
                //ss += ($"ver:{BitConverter.ToUInt16(b, 4)}\r\n");
                ss += ($"库温探头传感器温度:{modbusValueConvert(b, 6):##.#}\r\n");
                ss += ($"化霜探头传感器温度:{modbusValueConvert(b, 8):##.#}\r\n");
                ss += ($"制冷开机温度:{modbusValueConvert(b, 10):##.#}\r\n");
                ss += ($"制冷停机温度:{modbusValueConvert(b, 12):##.#}\r\n");
                ss += ($"制热开机温度:{modbusValueConvert(b, 14):##.#}\r\n");
                ss += ($"制热停机温度:{modbusValueConvert(b, 16):##.#}\r\n");
                var a1 = Convert.ToString(b[18], 2).PadLeft(8, '0');
                var a2 = Convert.ToString(b[19], 2).PadLeft(8, '0');
                var s1 = Convert.ToString(b[20], 2).PadLeft(8, '0');
                var s2 = Convert.ToString(b[21], 2).PadLeft(8, '0');

                temp = (double)BitConverter.ToInt16(b, 6) / 10;

                for (int i = 0; i < 8; i++)
                {
                    int p = 1 << i;
                    {
                        var xxx = b[18] & p;
                        if (xxx > 0)
                            als += AlertState[(uint)xxx] + ",";
                    }
                    {
                        var xxx = b[20] & p;
                        if (xxx > 0)
                            sls += RunState[(uint)xxx] + ",";
                    }
                }
                ss += ($"报警状态:{als}\r\n");
                ss += ($"设备状态:{sls}\r\n");
            }
            state = ss;
            //LogUtil.debug(ss);

            return temp;
        }

        static double modbusValueConvert(byte[] b, int index)
        {
            double sss;
            if (false && (uint)b[index + 1] >= 254)
            {
                b[index + 1] = 0x00;               
                sss = (double)BitConverter.ToInt16(b, index) / -10;
            }
            else
            {
                sss = (double)BitConverter.ToInt16(b, index) / 10;
            }
            return sss;
        }

        private static byte[] buildCheckData(byte[] sendData, int length)
        {
            ushort pChecksum = 0;
            AcSerialBean.CalculateCRC(sendData, length, out pChecksum);
            string checkStr = Convert.ToString(pChecksum, 16);
            byte[] checkByte = AcSerialBean.StringToByte(checkStr);

            if (checkByte.Length == 1)
            {
                sendData[length] = checkByte[0];
                sendData[length + 1] = 0x00;
            }
            else
            {
                sendData[length + 1] = checkByte[0];
                sendData[length] = checkByte[1];
            }
            return sendData;
        }

        private static int getReviceIntData(byte[] dataArray)
        {
            List<double> list = new List<double>();
            try
            {
                if (dataArray == null)
                {
                    return -1;
                }
                if (dataArray.Length >= 9)
                {
                    string data = String.Format("{0:X2}", dataArray[5]) + String.Format("{0:X2}", dataArray[6] + String.Format("{0:X2}", dataArray[3]) + String.Format("{0:X2}", dataArray[4]));
                    int tempV = Convert.ToInt32(data, 16);
                    return tempV;
                }
            }
            catch (Exception ex)
            {
                LogUtil.info(LogName + "转换出错:" + ex.ToString());
            }
            return -1;
        }

        private static List<double> getReviceData(byte[] dataArray)
        {
            List<double> list = new List<double>();
            try
            {
                if (dataArray == null)
                {
                    return list;
                }
                if (dataArray.Length >= 9)
                {

                    string temp = String.Format("{0:X2}", dataArray[3]) + String.Format("{0:X2}", dataArray[4]);
                    string hum = String.Format("{0:X2}", dataArray[5]) + String.Format("{0:X2}", dataArray[6]);
                    double tempV = (double)Convert.ToInt32(temp, 16) / 10;
                    double humV = (double)Convert.ToInt32(hum, 16) / 10;
                    list.Add(tempV);
                    list.Add(humV);
                }
            }
            catch (Exception ex)
            {
                LogUtil.info(LogName + "转换出错:" + ex.ToString());
            }
            return list;
        }

    }  /// <summary>
}