using CRClib;
using DataService.Model;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using ToolKitlib;


namespace NengLiang
{
    internal class NengLiang
    {
        /// <summary>
        /// 线程锁
        /// </summary>
        public static Object o = new Object();
        static log4net.ILog log;

        public static Socket serverSocket;
        /// <summary>
        /// 在线用户列表
        /// </summary>
        public static List<string> idOnLine = new List<string>();
        /// <summary>
        /// 存储IP及Socket--便于服务器与指定客户端通信
        /// </summary>
        public static Dictionary<string, Socket> OnLineDic = new Dictionary<string, Socket>();

        public static Encoding encoding = Encoding.Default;

        /// <summary>
        /// 地址码，[变量名，数据类型，可修改可读否(改-读)] ,变量个数
        /// </summary>
        public static Dictionary<int, string[]> RegisterType;//地址码00对应40001，其他地址以此类推[4区保持寄存器40001~49999]（绝对地址）

        /// <summary>
        /// 当前请求数据类型
        /// </summary>
        public static ushort index_id;
        /// <summary>
        /// 报文发送间隔时间
        /// </summary>
        public static int T = 1000;

        /// <summary>
        /// 循环获取数据时间
        /// </summary>
        public static int loopTime = 10;

        //public static float TRAS = 1000 / 2400 * 12.5f;//3.5字符周期周期时间（单位ms）
        public static float TRAS = 3.5f * 9 / 2.4f;//3.5字符周期周期时间（单位ms）单条发送周期时间
        //public static float TRAS = -1;//3.5字符周期周期时间（单位ms）单条发送周期时间

        /// <summary>
        /// 添加数据寄存器信息
        /// </summary>
        public static void AddDictionary()
        {
            if (RegisterType == null)
            {
                RegisterType = new Dictionary<int, string[]>();
                RegisterType.Add(0, new string[] { "瞬时流量", "ulong", "ny", "2" });
                RegisterType.Add(2, new string[] { "供水温度", "uint", "ny", "1" });
                RegisterType.Add(3, new string[] { "回水温度", "uint", "ny", "1" });
                RegisterType.Add(4, new string[] { "采样值", "uint", "ny", "1" });
                RegisterType.Add(5, new string[] { "累计流量整数", "ulong", "ny", "2" });
                RegisterType.Add(7, new string[] { "累计流量小数", "uint", "ny", "1" });
                RegisterType.Add(8, new string[] { "正累计流量整数", "ulong", "yy", "2" });
                RegisterType.Add(10, new string[] { "正累计流量小数", "uint", "ny", "1" });
                RegisterType.Add(11, new string[] { "负累计流量整数", "ulong", "yy", "2" });
                RegisterType.Add(13, new string[] { "负累计流量小数", "uint", "ny", "1" });
                RegisterType.Add(14, new string[] { "瞬时热量", "ulong", "ny", "2" });
                RegisterType.Add(16, new string[] { "修改版本号", "uint", "yy", "1" });
                RegisterType.Add(17, new string[] { "语言", "uint", "yy", "1" });
                RegisterType.Add(18, new string[] { "表地址", "uint", "yy", "1" });
                RegisterType.Add(19, new string[] { "仪表通讯速度", "uint", "yy", "1" });
                RegisterType.Add(20, new string[] { "修改口径", "uint", "yy", "1" });
                RegisterType.Add(21, new string[] { "流量单位", "uint", "yy", "1" });
                RegisterType.Add(22, new string[] { "流量积算单位", "uint", "yy", "1" });
                RegisterType.Add(23, new string[] { "零点采样值", "uint", "yy", "1" });
                RegisterType.Add(24, new string[] { "仪表系数", "uint", "yy", "1" });
                RegisterType.Add(25, new string[] { "热量系数", "uint", "yy", "1" });
                RegisterType.Add(26, new string[] { "供水温度系数", "uint", "yy", "1" });
                RegisterType.Add(27, new string[] { "回水温度系数", "uint", "yy", "1" });
                RegisterType.Add(28, new string[] { "小信号切除点", "uint", "yy", "1" });
                RegisterType.Add(29, new string[] { "修改脉冲单位", "uint", "yy", "1" });
                RegisterType.Add(30, new string[] { "允许切除显示", "uint", "yy", "1" });
                RegisterType.Add(31, new string[] { "反向输出允许", "uint", "yy", "1" });
                RegisterType.Add(32, new string[] { "电流输出类型", "uint", "yy", "1" });
                RegisterType.Add(33, new string[] { "脉冲输出方式", "uint", "yy", "1" });
                RegisterType.Add(34, new string[] { "频率输出范围", "uint", "yy", "1" });
                RegisterType.Add(35, new string[] { "空管报警允许", "uint", "yy", "1" });
                RegisterType.Add(36, new string[] { "空管报警阈值", "uint", "yy", "1" });
                RegisterType.Add(37, new string[] { "上限报警允许", "uint", "yy", "1" });
                RegisterType.Add(38, new string[] { "上限报警数值", "uint", "yy", "1" });
                RegisterType.Add(39, new string[] { "下限报警允许", "uint", "yy", "1" });
                RegisterType.Add(40, new string[] { "下限报警数值", "uint", "yy", "1" });
                RegisterType.Add(41, new string[] { "励磁报警允许", "uint", "yy", "1" });
                RegisterType.Add(42, new string[] { "传感器系数", "uint", "yy", "1" });
                RegisterType.Add(43, new string[] { "预留", "uint", "yy", "1" });
                RegisterType.Add(44, new string[] { "空管采样值", "uint", "ny", "1" });
                RegisterType.Add(45, new string[] { "报警信息", "uint", "ny", "1" });
                RegisterType.Add(46, new string[] { "电流零点修正", "uint", "yy", "1" });
                RegisterType.Add(47, new string[] { "电流满度修正", "uint", "yy", "1" });
                RegisterType.Add(48, new string[] { "仪表量程设置", "uint", "yy", "1" });
                RegisterType.Add(49, new string[] { "测量阻尼时间", "uint", "yy", "1" });
                RegisterType.Add(50, new string[] { "流量方向选择项", "uint", "yy", "1" });
                RegisterType.Add(51, new string[] { "累计热量整数", "ulong", "yy", "2" });
                RegisterType.Add(53, new string[] { "累计热量小数", "uint", "yy", "1" });
                RegisterType.Add(54, new string[] { "累计冷量整数", "ulong", "yy", "2" });
                RegisterType.Add(56, new string[] { "累计冷量小数", "uint", "yy", "1" });
            }
        }

        static void Main(string[] args)
        {
            //初始化日志
            log4net.Config.XmlConfigurator.Configure();
            log = log4net.LogManager.GetLogger("loginfo");
            AddDictionary();
            init();

            //var a = 0x36213;
            //ushort b = (ushort)Convert.ToInt16(a, 16);
            //byte g = (byte)(b / 256);//0x33
            //byte d = (byte)(b % 256);//0x2A
            //Console.ReadKey();

            while (true)
            {
                if (OnLineDic.Count == 0) continue;
                Thread.Sleep(1000 * loopTime);
                //var T = (int)Math.Ceiling(TRAS);
                Console.WriteLine("发送报文time " + T + " 毫秒,loop间隔 " + loopTime + " 秒");
                byte devAdd = 0x01;
                byte code = 0x03;
                ushort start = (ushort)0;
                ushort length = (0x0033);
                byte[] bytes;// 发送字节

                foreach (var v in OnLineDic.Values)
                {
                    Thread.Sleep(T);
                    bytes = ReadKsepRsgistecs(devAdd, code, start, length);
                    log.Info("发送至" + v.RemoteEndPoint + ": " + ToolKit.byteArrayToHexString(bytes));
                    v.Send(bytes);
                    //foreach (var item in RegisterType.Keys)
                    //{
                    //    if (T >= 0) { Thread.Sleep(T); }
                    //    else continue;
                    //    ushort start = (ushort)item;
                    //    ushort length = ushort.Parse(RegisterType[item][3].ToString());
                    //    bytes = ReadKsepRsgistecs(devAdd, code, start, length);
                    //    log.Info("发送至" + v.RemoteEndPoint + ": " + ToolKit.byteArrayToHexString(bytes));
                    //    //Console.WriteLine(ToolKit.byteArrayToHexString(bytes));
                    //    v.Send(bytes);
                    //    index_id = start;//记录当前请求数据 地址码
                    //}
                }
            }
        }

        /// <summary>
        /// 初始化服务器
        /// </summary>
        public static void init()
        {
            //TCP
            try
            {
                //var ip = "172.17.0.9";
                //var port = 12303;

                //var ip = "127.0.0.1";
                var ip = "10.16.56.3";
                var port = 8234;

                //调用socket(函数创建一个用于通信的套接字。
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //给已经创建的套接宁绑定一个端口号
                IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
                serverSocket.Bind(endPoint);

                //调用listen(函数使套接宁成为—个监听
                serverSocket.Listen(1000);//最大连接数

                //开启监听任务
                Task.Run(new Action(() =>
                {
                    ListenConnection();
                }));


                //开启输入任务
                Task.Run(new Action(() =>
                {
                    BaudRate();
                }));


            }
            catch (Exception e)
            {
                Console.WriteLine("服务器初始化异常:" + e.Message);
            }
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        private static void BaudRate()
        {
            while (true)
            {
                try
                {
                    var str = Console.ReadLine().ToLower();
                    if (str == "time")
                    { Console.Write("请输入报文间隔（毫秒）"); T = int.Parse(Console.ReadLine().ToLower()); }
                    else if (str == "loop")
                    { Console.Write("请输入循环时间（秒）"); loopTime = int.Parse(Console.ReadLine().ToLower()); }
                }
                catch (Exception e)
                {
                    Console.WriteLine("参数设置错误:" + e.Message + ",time默认1000毫秒，循环10秒");
                    T = 1000;
                    loopTime = 10;
                }

            }

        }

        /// <summary>
        /// 监听任务
        /// </summary>
        private static void ListenConnection()
        {
            while (true)
            {
                //调用accept() 函数来接受客户端的连接
                Socket clientSocket = serverSocket.Accept();//新用户连接后触发返回新的socket
                string ipPort = clientSocket.RemoteEndPoint.ToString();//连接用户的IP及端口
                addOnLine(ipPort, clientSocket, true);
                Console.WriteLine(clientSocket.RemoteEndPoint.ToString() + "上线了");
                Task.Run(() => ReceiveMsg(clientSocket));//针对单个客户端开启线程（接收）
                //Task.Run(() =>
                //{
                //    lock (o)
                //    {
                //        ReceiveMsg(clientSocket);
                //    }
                //});//针对单个客户端开启线程（接收）
            }
        }


        /// <summary>
        /// 接收消息--接收到进入触发
        /// </summary>
        /// <param name="clientSocket"></param>
        private static void ReceiveMsg(Socket clientSocket)
        {
            StringBuilder builder_shuju = new StringBuilder("");//需校验字节
            StringBuilder builder_crc = new StringBuilder("");//收到检验位
            while (true)
            {
                byte[] bytes = new byte[1024];
                int length = -1;
                try
                {
                    length = clientSocket.Receive(bytes);//返回字节数
                }
                catch (Exception)
                {
                    //用户下线--更新在线列表
                    addOnLine(clientSocket.RemoteEndPoint.ToString(), clientSocket, false);
                    Console.WriteLine(clientSocket.RemoteEndPoint.ToString() + "下线了");
                    break;//结束线程
                }
                if (length == 0)
                {
                    //用户下线--更新在线列表
                    addOnLine(clientSocket.RemoteEndPoint.ToString(), clientSocket, false);
                    Console.WriteLine(clientSocket.RemoteEndPoint.ToString() + "下线了");
                    break;//结束线程
                }

                if (length > 0)
                {
                    //string message = Encoding.Default.GetString(bytes, 0, length);
                    string _message = ToolKit.byteArrayToHexString(bytes, length);//带空格报文
                    string message = _message.Replace(" ", "");//不带空格报文

                    //var message = _message.Split(' ');//不带空格报文
                    //List<byte> lines = new List<byte>();
                    //for (int i = 0; i < message.Length; i++)
                    //{
                    //    lines.Add((byte)Convert.ToInt16(message[i], 16));
                    //}
                    //byte[] messageBytes = ToolKit.listToBytes(lines);


                    //CRC校验--失败返回不解析
                    builder_shuju.Clear();
                    builder_crc.Clear();
                    for (int i = 0; i < message.Length - 4; i++)
                    {
                        builder_shuju.Append(message[i]);
                    }
                    for (int i = message.Length - 4; i < message.Length; i++)
                    {
                        builder_crc.Append(message[i]);
                    }
                    if (CRC.CRCForModbus(builder_shuju.ToString().ToUpper()) != builder_crc.ToString().ToUpper())
                    {
                        log.Info("接收" + clientSocket.RemoteEndPoint + "数据校验失败" + ": " + _message);
                        Console.WriteLine("接收" + clientSocket.RemoteEndPoint + "数据校验失败" + ": " + _message);
                    }
                    else
                    {
                        //执行解析
                        log.Info("接收自" + clientSocket.RemoteEndPoint + ": " + _message);
                        JudgmentFunction(bytes);
                    }
                    ////执行解析
                    //log.Info("接收自" + clientSocket.RemoteEndPoint + ": " + _message);
                    //JudgmentFunction(bytes);
                }
            }
        }

        /// <summary>
        /// 更新在线用户列表
        /// </summary>
        /// <param name="clientIp">用户IP端口号套接</param> 
        /// <param name="clientSocket">Socket</param>
        /// <param name="isAdd">用是否增加</param>
        private static void addOnLine(string clientIp, Socket clientSocket, bool isAdd)
        {
            try
            {
                if (isAdd)
                {
                    idOnLine.Add(clientIp);
                    OnLineDic.Add(clientIp, clientSocket);
                }
                else
                {
                    idOnLine.Remove(clientIp);
                    OnLineDic.Remove(clientIp);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("更新在线用户异常:" + e.Message);
            }
            //Invoke(new Action(() =>
            //{
            //    if (isAdd) { idOnLine.Add(clientIp); }
            //    else { idOnLine.Remove(clientIp); }
            //}));

        }

        /// <summary>
        /// 判断功能类型
        /// </summary>
        /// <param name="message"></param>
        public static void JudgmentFunction(/*string message*/byte[] message)
        {
            try
            {
                //tring order = message[2].ToString() + message[3].ToString();//命令
                var order = message[1];//命令

                //var key = (int)index_id;//获取 地址码 
                if (order == 0x03)//读取命令
                {
                    //if (!RegisterType.ContainsKey(key) || RegisterType[key][2][1] == 'n') return;
                    readData(message);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("判断功能类型异常:" + e.Message);
            }
        }

        /// <summary>
        /// 读取保存寄存器指令
        /// </summary>
        /// <param name="devAdd">地址</param>
        /// <param name="code">功能码</param>
        /// <param name="start">起始地址</param>
        /// <param name="length">变量个数</param>
        /// <returns></returns>
        public static byte[] ReadKsepRsgistecs(byte devAdd, byte code, ushort start, ushort length)
        {
            //拼接报文
            List<byte> sendCommand = new List<byte>();//地址 + 功能码 + 起始地址 + 变量个数 + 校验码
            sendCommand.Add(devAdd);//地址
            sendCommand.Add(code);//功能码
            sendCommand.Add((byte)(start / 256));//起始地址--高位
            sendCommand.Add((byte)(start % 256));//起始地址--地位
            sendCommand.Add((byte)(length / 256));//变量个数--高位
            sendCommand.Add((byte)(length % 256));//变量个数--地位
            byte[] astr = ToolKit.listToBytes(sendCommand);
            string a = CRC.CRCForModbus(ToolKit.byteArrayToHexString(astr));
            sendCommand.Add(ToolKit.stringToByteArray(a)[0]); //校验码-- 高位
            sendCommand.Add(ToolKit.stringToByteArray(a)[1]); //校验码-- 地位

            //发送报文
            //sendCommand.ToArray();
            //Thread.Sleep(40);
            byte[] bytes = ToolKit.listToBytes(sendCommand);
            //接收报文

            //校验报文--验证长度--验证站--验证功能码


            //解析报文

            return bytes;
        }

        /// <summary>
        /// 读取命令
        /// </summary>
        /// <param name="message"></param>
        /// <param name="key">地址码</param>
        public static void readData(byte[] message)
        {
            energy_data energy_Data = new energy_data();
            try
            {
                int a = 3; //message[3]开始
                List<byte> by = new List<byte>();
                var _readSum = message[2];
                int readSum = (int)message[2];//变量总字节数
                foreach (var item in RegisterType.Keys)
                {
                    for (int i = a; i < a + int.Parse(RegisterType[item][3])*2; i++)
                    {
                        by.Add(message[i]);
                    }
                    a += by.Count;
                    byte[] data = ToolKit.listToBytes(by);//每组数值
                    string H16 = ToolKit.byteArrayToHexString(data).Replace(" ", "");
                    var num = Convert.ToInt64(H16, 16);//获取值
                    var aa = RegisterType[item][1].ToLower();
                    if (aa == "ulong")
                    {
                        var number = (ulong)num;
                        analysisUlong(RegisterType[item][0], number, energy_Data);
                    }
                    else
                    {
                        var number = (uint)num;
                        analysisUnit(RegisterType[item][0], number, energy_Data);
                    }
                    by.Clear();
                }
                //energy_data对象取值完毕
                try
                {
                    energy_Data.positive_total_flow = Convert.ToDecimal(energy_Data.positive_total_flowA + "." + energy_Data.positive_total_flowB);
                    energy_Data.cumulative_traffic = Convert.ToDecimal(energy_Data.cumulative_trafficA + "." + energy_Data.cumulative_trafficB);
                    energy_Data.negative_total_flow = Convert.ToDecimal(energy_Data.negative_total_flowA + "." + energy_Data.negative_total_flowB);
                    energy_Data.cumulative_heat = Convert.ToDecimal(energy_Data.cumulative_heatA + "." + energy_Data.cumulative_heatB);
                    energy_Data.cumulative_cooling_capacity = Convert.ToDecimal(energy_Data.cumulative_cooling_capacityA + "." + energy_Data.cumulative_cooling_capacityB);
                    energy_Data.energy_id = Guid.NewGuid().ToString("N");
                    energy_Data.input_date = DateTime.Now;
                    energy_Data.create_time = DateTime.Now;
                    DataService.BLL.energy_data edb = new DataService.BLL.energy_data();
                    edb.Add(energy_Data);
                    Console.WriteLine("插入数据库成功!");
                }
                catch(Exception ex)
                {
                    Console.WriteLine("插入数据库失败!");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("读取命令异常:" + e.Message);
            }
        }


        /// <summary>
        /// unit值类型解析
        /// </summary>
        /// <param name="name">变量名</param>
        /// <param name="number"></param>
        public static void analysisUnit(string name, uint number, energy_data ed)
        {

            if (name == "供水温度")
            {
                number /= 100;
                Console.WriteLine(name + ":" + number + "℃");
                ed.supply_water_temperature = number;
            }
            else if (name == "回水温度")
            {
                number /= 100;
                Console.WriteLine(name + ":" + number + "℃");
                ed.return_water_temperature = number;
            }
            else if (name == "采样值")
            {
                Console.WriteLine(name + ":" + number);
                ed.sampling_value = number;
            }
            else if (name == "累计流量小数")
            {
                Console.WriteLine(name + ":0." + number);
                ed.cumulative_trafficB = number.ToString();
            }
            else if (name == "正累计流量小数")
            {
                Console.WriteLine(name + ":0." + number);
                ed.positive_total_flowB = number.ToString();
            }
            else if (name == "负累计流量小数")
            {
                Console.WriteLine(name + ":0." + number);
                ed.negative_total_flowB = number.ToString();
            }
            else if (name == "修改版本号")
            {
                Console.WriteLine(name + ":" + number);
                ed.revised_version_number = number.ToString();
            }
            else if (name == "语言")
            {
                if (number == 0) { Console.WriteLine(name + ":中文"); ed.lang = "中文"; }
                else if (number == 1) { Console.WriteLine(name + ":英文"); ed.lang = "英文"; }
            }
            else if (name == "表地址")
            {
                Console.WriteLine(name + ":" + number);
                ed.table_address = number.ToString();
            }
            else if (name == "仪表通讯速度")
            {
                //float TRAS;//3.5字符周期周期时间（单位ms）
                if (number == 0) { Console.WriteLine(name + ":300"); ed.meter_communication_speed = 300;/*TRAS = 1000 / 300 * 12.5f;*/ TRAS = 3.5f * 9 / 0.3f; }
                else if (number == 1) { Console.WriteLine(name + ":2400"); ed.meter_communication_speed = 2400;/*TRAS = 1000 / 2400 * 12.5f;*/ TRAS = 3.5f * 9 / 2.4f; }
                else if (number == 2) { Console.WriteLine(name + ":14400"); ed.meter_communication_speed = 14400; /*TRAS = 1000 / 14400 * 12.5f; */TRAS = 3.5f * 9 / 14.4f; }
                else if (number == 3) { Console.WriteLine(name + ":600"); ed.meter_communication_speed = 600; /*TRAS = 1000 / 600 * 12.5f; */TRAS = 3.5f * 9 / 0.6f; }
                else if (number == 4) { Console.WriteLine(name + ":4800"); ed.meter_communication_speed = 4800;/* TRAS = 1000 / 4800 * 12.5f;*/ TRAS = 3.5f * 9 / 4.8f; }
                else if (number == 5) { Console.WriteLine(name + ":19200"); ed.meter_communication_speed = 19200;/*TRAS = 1000 / 19200 * 12.5f;*/ TRAS = 3.5f * 9 / 19.2f; }
                else if (number == 6) { Console.WriteLine(name + ":1200"); ed.meter_communication_speed = 1200;/*TRAS = 1000 / 1200 * 12.5f; */TRAS = 3.5f * 9 / 1.2f; }
                else if (number == 7) { Console.WriteLine(name + ":9600"); ed.meter_communication_speed = 9600;/*TRAS = 1000 / 9600 * 12.5f;*/ TRAS = 3.5f * 9 / 9.6f; }
                else if (number == 8) { Console.WriteLine(name + ":38400"); ed.meter_communication_speed = 38400;/*TRAS = 1000 / 38400 * 12.5f;*/ TRAS = 3.5f * 9 / 38.4f; }

            }
            else if (name == "修改口径")
            {
                Console.WriteLine(name + ":" + number);
                ed.modified_caliber = number;
            }
            else if (name == "流量单位")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":L/H");
                    ed.flow_unit = "L/H";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":L/M");
                    ed.flow_unit = "L/M";
                }
                else if (number == 2)
                {
                    Console.WriteLine(name + ":L/S");
                    ed.flow_unit = "L/S";
                }
                else if (number == 3)
                {
                    Console.WriteLine(name + ":M³/H");
                    ed.flow_unit = "M³/H";
                }
                else if (number == 4)
                {
                    Console.WriteLine(name + ":M³/M");
                    ed.flow_unit = "M³/M";
                }
                else if (number == 5)
                {
                    Console.WriteLine(name + ":M³/S");
                    ed.flow_unit = "M³/S";
                }
            }
            else if (name == "流量积算单位")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":0.001L");
                    ed.flow_integration_unit = "0.001L";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":0.001M³");
                    ed.flow_integration_unit = "0.001M³";
                }
                else if (number == 2)
                {
                    Console.WriteLine(name + ":0.01L");
                    ed.flow_integration_unit = "0.01L";
                }
                else if (number == 3)
                {
                    Console.WriteLine(name + ":0.1L");
                    ed.flow_integration_unit = "0.1L";
                }
                else if (number == 4)
                {
                    Console.WriteLine(name + ":1L");
                    ed.flow_integration_unit = "1L";
                }
                else if (number == 5)
                {
                    Console.WriteLine(name + ":0.01M³");
                    ed.flow_integration_unit = "0.01M³";
                }
                else if (number == 6)
                {
                    Console.WriteLine(name + ":0.1M³");
                    ed.flow_integration_unit = "0.1M³";
                }
                else if (number == 7)
                {
                    Console.WriteLine(name + ":1M³");
                    ed.flow_integration_unit = "1M³";
                }
            }
            else if (name == "零点采样值")
            {
                Console.WriteLine(name + ":" + number);
                ed.zero_sample_value = number;
            }
            else if (name == "仪表系数")
            {
                Console.WriteLine(name + ":" + number);
                ed.meter_factor = number;
            }
            else if (name == "热量系数")
            {
                Console.WriteLine(name + ":" + number);
                ed.heat_coefficient = number;
            }
            else if (name == "供水温度系数")
            {
                Console.WriteLine(name + ":" + number);
                ed.supply_water_temperature_coefficient = number;
            }
            else if (name == "回水温度系数")
            {
                Console.WriteLine(name + ":" + number);
                ed.return_temperature_coefficient = number;
            }
            else if (name == "小信号切除点")
            {
                Console.WriteLine(name + ":" + number);
                ed.small_signal_cut_off_point = number;
            }
            else if (name == "修改脉冲单位")
            {
                Console.WriteLine(name + ":" + number);
                ed.modify_pulse_unit = number;
            }
            else if (name == "允许切除显示")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":允许");
                    ed.allow_cutout_display = "允许";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":禁止");
                    ed.allow_cutout_display = "禁止";
                }
            }
            else if (name == "反向输出允许")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":允许");
                    ed.ReverseOutputAllows = "允许";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":禁止");
                    ed.ReverseOutputAllows = "禁止";
                }
            }
            else if (name == "电流输出类型")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":0~10mA");
                    ed.current_output_type = "0~10mA";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":4~20mA");
                    ed.current_output_type = "4~20mA";
                }
            }
            else if (name == "脉冲输出方式")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":频率");
                    ed.pulse_output_mode = "频率";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":脉冲");
                    ed.pulse_output_mode = "脉冲";
                }
            }
            else if (name == "频率输出范围")
            {
                Console.WriteLine(name + ":" + number);
                ed.frequency_output_range = number.ToString();
            }
            else if (name == "空管报警允许")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":允许");
                    ed.empty_traffic_alarm_allowed = "允许";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":禁止");
                    ed.empty_traffic_alarm_allowed = "禁止";
                }
            }
            else if (name == "空管报警阈值")
            {
                Console.WriteLine(name + ":" + number);
                ed.empty_traffic_alarm_threshold = number;
            }
            else if (name == "上限报警允许")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":允许");
                    ed.high_limit_alarm_allows = "允许";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":禁止");
                    ed.high_limit_alarm_allows = "禁止";
                }
            }
            else if (name == "上限报警数值")
            {
                Console.WriteLine(name + ":" + number);
                ed.upper_alarm_value = number;
            }
            else if (name == "下限报警允许")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":允许");
                    ed.lower_limit_alarm_allowed = "允许";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":禁止");
                    ed.lower_limit_alarm_allowed = "禁止";
                }
            }
            else if (name == "下限报警数值")
            {
                Console.WriteLine(name + ":" + number);
                ed.lower_limit_alarm_value = number;
            }
            else if (name == "励磁报警允许")
            {
                if (number == 0)
                {
                    Console.WriteLine(name + ":允许");
                    ed.excitation_alarm_allows = "允许";
                }
                else if (number == 1)
                {
                    Console.WriteLine(name + ":禁止");
                    ed.excitation_alarm_allows = "禁止";
                }
            }
            else if (name == "传感器系数")
            {
                Console.WriteLine(name + ":" + number);
                ed.sensor_coefficient = number;
            }
            else if (name == "预留")
            {
                Console.WriteLine(name + ":" + number);
            }
            else if (name == "空管采样值")
            {
                Console.WriteLine(name + ":" + number);
                ed.empty_pipe_sampling_value = number;
            }
            else if (name == "报警信息")
            {
                if (number == 1)
                {
                    Console.WriteLine(name + ":瞬时流量单位选择错误");
                    ed.alarm_information = "瞬时流量单位选择错误";
                }
                else if (number == 2)
                {
                    Console.WriteLine(name + ":空管");
                    ed.alarm_information = "空管";
                }
                else if (number == 4)
                {
                    Console.WriteLine(name + ":下限报警");
                    ed.alarm_information = "下限报警";
                }
                else if (number == 8)
                {
                    Console.WriteLine(name + ":上限报警");
                    ed.alarm_information = "上限报警";
                }
            }
            else if (name == "电流零点修正")
            {
                Console.WriteLine(name + ":" + number);
                ed.current_zero_correction = number;
            }
            else if (name == "电流满度修正")
            {
                Console.WriteLine(name + ":" + number);
                ed.current_full_scale_correction = number;
            }
            else if (name == "仪表量程设置")
            {
                Console.WriteLine(name + ":" + number);
                ed.meter_range_setting = number.ToString();
            }
            else if (name == "测量阻尼时间")
            {
                Console.WriteLine(name + ":" + number);
                ed.measure_damping_time = number.ToString();
            }
            else if (name == "流量方向选择项")
            {
                Console.WriteLine(name + ":" + number);
                ed.flow_direction_option = number.ToString();
            }
            else if (name == "累计热量小数")
            {
                Console.WriteLine(name + ":0." + number);
                ed.cumulative_heatB = number.ToString();
            }
            else if (name == "累计冷量小数")
            {
                Console.WriteLine(name + ":0." + number);
                ed.cumulative_cooling_capacityB = number.ToString();
            }

        }

        /// <summary>
        /// ulong值类型解析
        /// </summary>
        /// <param name="name">变量名</param>
        /// <param name="number"></param>
        public static void analysisUlong(string name, ulong number, energy_data ed)
        {
            if (name == "瞬时流量")
            {
                number /= 1000;//此值单位为升 / 小时，需要除以 1000 得到立方米 / 小时
                Console.WriteLine(name + ":" + number + "m³/h");
                ed.instantaneous_delivery = number;
            }
            else if (name == "累计流量整数")
            {
                Console.WriteLine(name + ":" + number);
                ed.cumulative_trafficA = number.ToString();
            }
            else if (name == "正累计流量整数")
            {
                Console.WriteLine(name + ":" + number);
                ed.positive_total_flowA = number.ToString();
            }
            else if (name == "负累计流量整数")
            {
                Console.WriteLine(name + ":" + number);
                ed.negative_total_flowA = number.ToString();
            }
            else if (name == "瞬时热量")//单位为 KJ/h（千焦每小时），若想得到 MJ/h 则需要除以 1000；换算成 KWh/h 需要除以 3600，
            {
                Console.WriteLine(name + ":" + number + "KJ/h");
                ed.instant_heat = number;
            }
            else if (name == "累计热量整数")
            {
                Console.WriteLine(name + ":" + number);
                ed.cumulative_heatA = number.ToString();
            }
            else if (name == "累计冷量整数")
            {
                Console.WriteLine(name + ":" + number);
                ed.cumulative_cooling_capacityA = number.ToString();
            }

        }

        /// <summary>
        /// 寄存器类型
        /// </summary>
        public enum qRegisterType
        {
            //不可修改可读
            瞬时流量,
            供水温度 = 2,
            回水温度,
            采样值,
            累计流量整数,
            累计流量小数 = 7,

            //可修改可读
            正累计流量整数,

            //不可修改可读
            正累计流量小数 = 10,

            //可修改可读
            负累计流量整数,

            //不可修改可读
            负累计流量小数 = 13,
            瞬时热量,

            //可修改可读
            修改版本号 = 16,
            语言,
            表地址,
            仪表通讯速度,
            修改口径,
            流量单位,
            流量积算单位,
            零点采样值,
            仪表系数,
            热量系数,
            供水温度系数,
            回水温度系数,
            小信号切除点,
            修改脉冲单位,
            允许切除显示,
            反向输出允许,
            电流输出类型,
            脉冲输出方式,
            频率输出范围,
            空管报警允许,
            空管报警阈值,
            上限报警允许,
            上限报警数值,
            下限报警允许,
            下限报警数值,
            励磁报警允许,
            传感器系数,
            预留,

            //不可修改可读
            空管采样值,
            报警信息,

            //可修改可读
            电流零点修正,
            电流满度修正,
            仪表量程设置,
            测量阻尼时间,
            流量方向选择项,
            累计热量整数,
            累计热量小数 = 53,
            累计冷量整数,
            累计冷量小数 = 56,
        }


    }
}


