using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HTCoreServiceApp.DriverInterface;
using HTCoreServiceApp.Models;
using System.Threading;
using HTCoreServiceApp.Common;
using System.Collections;
using System.Text.RegularExpressions;
using HTCoreServiceApp.DataHandle;
using System.Timers;
using Newtonsoft.Json.Linq;
using System.Net;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Pipelines.Sockets.Unofficial.Arenas;
using System.Numerics;

namespace HTCoreServiceApp.Communicate.ModbusTcp
{
    public class ModbusTcpClientExample : IDriverEntity
    {

        public string DeviceId { get; set; }

        private string DriverName { get; set; }
        private List<MetaSystem> Systems { get; set; }
        public bool IsConnected { get; set; }

        public int Timeout { get; set; }

        public bool isScan { get; set; }

        public System.Timers.Timer ScanTimer { get ; set; }

		System.Timers.Timer timerCheck = new System.Timers.Timer();

        //public List<System.Threading.Timer> Timers { get; set; }
        public List<ScanTimer> ScanTimers { get; set; }

        public string Address = "127.0.0.1";
        private int Port = 0;
        private int SlaveID = 0;

        private string PLCType = "";

        public ModbusClient Client;
        private byte[] Buffer = new byte[65536];
        private byte[] DB_A = new byte[1024];
        private byte[] DB_B = new byte[1024];
        private byte[] DB_C = new byte[1024];
        private readonly object _lock = new();


        private List<MetaGroup> MetaGroups;
        private List<MetaTag> MetaTags;
        //List<Argument> argument, List<MetaGroup> metaGroups,List<MetaTag> metaTags
        public ModbusTcpClientExample(TagGroup tagGroup) 
        {
            Client = new ModbusClient();

            ScanTimers = new List<ScanTimer>();

            Address =tagGroup.Arguments.Where(x => x.PropertyName == "ServerName").First().PropertyValue;
            Port = int.Parse(tagGroup.Arguments.Where(x => x.PropertyName == "Port").First().PropertyValue);
            SlaveID = int.Parse(tagGroup.Arguments.Where(x => x.PropertyName == "SlaveID").First().PropertyValue);
            PLCType = tagGroup.Arguments.Where(x => x.PropertyName == "PLCType").First().PropertyValue;
            Timeout = int.Parse(tagGroup.Arguments.Where(x => x.PropertyName == "TimeOut").First().PropertyValue);
            MetaGroups =tagGroup.Groups;
            MetaTags = tagGroup.Tags;//只有一组
            DriverName = tagGroup.DriverName;
            Systems = tagGroup.Systems;

            //Client.SetConnectionType(0x3);
            Client.ConnectionTimeout= Timeout;
            //Client.RecvTimeout = 30;



			//Connect();
			timerCheck.Interval = 2000;
			StartConnectCheck();

            StartScan();
        }

        public void StartScan()
        {
            var groups = MetaGroups.GroupBy(x => new { x.GroupId });

            var scanTagsParas = new List<ScanTagsPara>();

            foreach (var metaGroup in groups)
            {
                ScanTagsPara scanTagsPara = new ScanTagsPara();
                scanTagsPara.GroupName = MetaGroups.Where(x=>x.GroupId == metaGroup.Key.GroupId).ToList().First().GroupName;
                scanTagsPara.UpdateRate = MetaGroups.Where(x => x.GroupId == metaGroup.Key.GroupId).ToList().First().UpdateRate;
                scanTagsPara.IsConsecutive = (bool)MetaGroups.Where(x => x.GroupId == metaGroup.Key.GroupId).ToList().First().IsActive;
                scanTagsPara.IsActive = MetaGroups.Where(x => x.GroupId == metaGroup.Key.GroupId).ToList().First().IsActive;
                scanTagsPara.ScanTags  = MetaTags.Where(x => x.GroupId == metaGroup.Key.GroupId).ToList();
                if (scanTagsPara.ScanTags.Count < 1)
                {
                    continue;
                }
                short driverID = (short)MetaGroups.Where(x => x.GroupId == metaGroup.Key.GroupId).ToList().First().DriverId;
                scanTagsPara.DriverName = DriverName;
                var groupSysId = MetaGroups.Where(x => x.GroupId == metaGroup.Key.GroupId).ToList().First().SystemId;
                scanTagsPara.SystemName = Systems.Where(x => x.SystemId == groupSysId).ToList().First().SystemName;
                scanTagsPara.AddressArg = PLCHelper.GetAddressArg_Modbus_Word(scanTagsPara.ScanTags);
                scanTagsParas.Add(scanTagsPara);
            }
            //if 添加连续或单变量读取标记
            //if (scanTagsPara.IsConsecutive == true)
            //{
            //    if (scanTagsPara.IsActive == true && scanTagsPara.ScanTags.Count > 0)
            //        Task.Run(() =>
            //        {
            //            ScanConsecutive(scanTagsPara);
            //        }) ;
            //}
            //else
            //{
            //    if (scanTagsPara.IsActive == true && scanTagsPara.ScanTags.Count > 0)
            //        Task.Run(() =>
            //        {
            //            Scan(scanTagsPara);
            //        });

            //}
            ScanConsecutive(scanTagsParas);
        }

        /// <summary>
        /// 启动连续读取
        /// </summary>
        /// <param name="scanTagsParas"></param>
        public void ScanConsecutive(List<ScanTagsPara> scanTagsParas)
        {
            foreach (var scanTagsPara in scanTagsParas)
            {
                ScanTimer timerScan = new ScanTimer();
                var Interval = scanTagsPara.UpdateRate;
                if (Interval <= 0)
                {
                    Interval = 1000;
                }
                timerScan.ScanTagsPara = scanTagsPara;
                //timerScan.AddressArg = PLCHelper.GetAddressArg(scanTagsParas.ScanTags);
                if (scanTagsPara.IsConsecutive == true)
                    timerScan.Timer = new System.Threading.Timer(TimerScanConsecutive_Elapsed, timerScan.ScanTagsPara, 0, (int)Interval);
                //else
                //    timerScan.Timer = new System.Threading.Timer(TimerScanDisperse_Elapsed, timerScan.ScanTagsPara, 0, (int)Interval);
                //timerScan.Enabled = true;
                ScanTimers.Add(timerScan);
            }
        }
        /// <summary>
        /// 连续读取timer事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimerScanConsecutive_Elapsed(System.Object stateInfo)
        {
            long hdatetime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
            ScanTagsPara scanTagsPara = (ScanTagsPara)stateInfo;
            //AddressArg addressArg = timerScan.AddressArg;
            
            if (scanTagsPara.IsActive == false)
                return;
            if (Client.Connected)
            {

                var addressArg = scanTagsPara.AddressArg;

                //object _lock = new();

                Task task = Task.Factory.StartNew(() =>
                {
                    lock (_lock)
                    {
                        try
                        {
                            var tcollstart = DateTime.Now;
                            //CodingTools.StartTime = DateTime.Now.Millisecond;//de
                            //scanTagsPara.ScanTags.Min(x => x.Address);
                            //scanTagsPara.ScanTags.Min(x => x.Address);提高速度应放在timer事件前，测试后更改
                            int startAdress = addressArg.Start;
                                
                            int amount = addressArg.Length;
                            int[] buffer = new int[amount];
                            int pdu = 122;
                            string Result = "";
                            if (amount <= pdu)
                            {
                                Result = ReadHoldingRegisters( startAdress, amount, ref buffer);
                            }
                            else
                            {
                               
                                //int additional = amount- pdu;
                                int forCount = (int)Math.Ceiling(float.Parse(((float)amount / (float)pdu).ToString()));
                                List<int[]> bytes= new List<int[]>();
                                for (int i = 0; i < forCount; i++)
                                {
                                    if ((amount - (i * pdu)) > pdu)
                                    {
                                        int start = startAdress + i * pdu;
                                        int[] bytes1 = new int[pdu];
                                        Result = ReadHoldingRegisters(start, pdu, ref bytes1);
                                        bytes.Add(bytes1);
                                    }
                                    else
                                    {
                                        int start = startAdress + i * pdu;
                                        int[] bytes1 = new int[amount - (i * pdu)];
                                        Result = ReadHoldingRegisters(start, amount - (i * pdu), ref bytes1);
                                        bytes.Add(bytes1);
                                    }
                                }
                                var byetstemp = Array.Empty<int>();
                                foreach (var buff in bytes)
                                {
                                    byetstemp = byetstemp.Concat(buff).ToArray();
                                }
                                buffer = byetstemp;
                            }
                            var tcollend = DateTime.Now;
                            var timecolldiff =  tcollend - tcollstart;
                            Console.WriteLine($"ModbusTcp读取耗时：{timecolldiff},设备:{DriverName}变量组:{scanTagsPara.GroupName}");
                            //CodingTools.EndTime = DateTime.Now.Millisecond;//de
                            //var timess = (CodingTools.EndTime - CodingTools.StartTime).ToString();
                            //Console.WriteLine($"读取耗时：{timess}");
                            if (Result == "")
                            {
                                var t1 = DateTime.Now.Millisecond;
                                Console.WriteLine(string.Join(",", buffer) + "ModbusTcp读取完成：" + " 字数：" + amount.ToString());
                                //Task<int> saveResult = DataExtract.DataExtractCAsync(scanTagsPara.ScanTags, scanTagsPara.GroupName, scanTagsPara.DriverName, buffer, addressArg);
                                DataExtractMB.DataExtractCAsync(scanTagsPara.ScanTags, scanTagsPara.SystemName, scanTagsPara.GroupName, scanTagsPara.DriverName, buffer, addressArg);
                                var t2 = DateTime.Now.Millisecond;
                                var timediff = t2 - t1;
                                Console.WriteLine($"ModbusTcp缓存和储存耗时：{timediff}");
                                {
                                    //if (saveResult.Result == 0)
                                    //{
                                    //    //logger
                                    //}
                                    //else
                                    //{
                                    //    //logger
                                    //}

                                }
                            }
                            else if (Result != "")
                            {
                                Console.WriteLine("MB读取失败："+" ERROR：" + Result.ToString());
								LogHelper.LogWrite("MB读取失败："+" ERROR：" + Result.ToString());
								//Close();
								//Thread.Sleep(50);
								//Connect();
							}

                        }
                        catch (Exception ex)
                        {
                            LogHelper.LogWrite($"{DriverName}读取失败，MB错误信息{ex}");
                        }
                    }

                });
            }
            else
            {
				LogHelper.LogWrite($"{DriverName}读取失败，MB未连接");
				//Connect();
			}
            Thread.Sleep(50);
            
        }
        /*
        /// <summary>
        /// 启动单个变量读取
        /// </summary>
        /// <param name="scanTagsPara"></param>
        public void Scan(ScanTagsPara scanTagsPara)
        {
            ScanTimer timerScan = new ScanTimer();
            if (scanTagsPara.UpdateRate > 0)
            {
                timerScan.Interval = (double)scanTagsPara.UpdateRate;
            }
            else
            {
                timerScan.Interval = 1000;
            }
            timerScan.ScanTagsPara = scanTagsPara;
            timerScan.Elapsed += new System.Timers.ElapsedEventHandler(TimerScan_Elapsed);
            timerScan.Enabled = true;
        }

        /// <summary>
        /// 单个变量读取timer事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimerScan_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            ScanTimer timerScan = (ScanTimer)sender;
            ScanTagsPara scanTagsPara = timerScan.ScanTagsPara;
            AddressArg addressArg = timerScan.AddressArg;
            if (IsConnected = true)
            {
                object _lock = new();

                Task task = Task.Run(() =>
                {
                    lock (_lock)
                    {
                        try
                        {
                            //CodingTools.StartTime = DateTime.Now.Millisecond;//de
                            //scanTagsPara.ScanTags.Min(x => x.Address);
                            //scanTagsPara.ScanTags.Min(x => x.Address);提高速度应放在timer事件前，测试后更改
                            int startAdress = addressArg.Start;
                            int Area = 132;
                            int DBNumber = 0;
                            if (scanTagsPara.GroupName.Contains("DB"))
                            {
                                DBNumber = int.Parse(Regex.Replace(scanTagsPara.GroupName, "[a-z]", "", RegexOptions.IgnoreCase));
                            }
                            else
                            {
                                DBNumber = int.Parse(scanTagsPara.GroupName);
                            }
                            int amount = addressArg.Length;
                            int WordLen = 2;
                            byte[] buffer = new byte[amount];
                            int Result = ReadArea(Area, DBNumber, startAdress, amount, WordLen, ref buffer);
                            //CodingTools.EndTime = DateTime.Now.Millisecond;//de
                            //var timess = (CodingTools.EndTime - CodingTools.StartTime).ToString();
                            //Console.WriteLine($"读取耗时：{timess}");
                            if (Result == 0)
                            {
                                //Console.WriteLine(string.Join(",", buffer) + "读取完成：DB" + DBNumber.ToString() + ",字节数：" + amount.ToString());
                                int saveResult = DataExtract.DataExtractConsecutive(timerScan.ScanTagsPara.ScanTags, scanTagsPara.GroupName, timerScan.ScanTagsPara.DriverName, buffer, addressArg);
                                {
                                    if (saveResult == 0)
                                    {
                                        //logger
                                    }
                                    else
                                    {
                                        //logger
                                    }

                                }
                            }
                            else if (Result != 0)
                            {
                                Console.WriteLine("读取失败：DB" + DBNumber.ToString() + ",ERRORCODE：" + Result.ToString());
                                Close();
                                Thread.Sleep(200);
                                Connect();
                            }

                        }
                        catch (Exception ex)
                        {

                        }
                    }

                });
            }
            else
            {
                Connect();
            }
        }
        */
        public string ReadHoldingRegisters(int start, int Amount,ref int[] buffer)
        {
            object _lock = new();
            var Result = "";
            lock (_lock)
            {
                try
                {
                    int reval = 0;
                    int SizeRead = 0;
                    
                    //buffer = new byte[65536];
                    buffer = Client.ReadHoldingRegisters(start, Amount);
                    return Result;
                }
                catch(Exception ex)
                {
                    return Result = ex.ToString();
                }
            }
        }

		public void StartConnectCheck()
		{
			
			timerCheck.Elapsed += new System.Timers.ElapsedEventHandler(TimerCheckConnect_Elapsed);
			timerCheck.Enabled = true;
		}

        private void TimerCheckConnect_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
			timerCheck.Enabled = false;
			if (Client.Connected)
            {
				timerCheck.Enabled = true;
				return;
            }
            else
            {
                Connect();
			}
        }


		public bool Connect()
        {
            var Result = "";
            try
            {

                Client.Connect(Address, Port);
            }
            catch(Exception ex)
            {
                Result = ex.ToString();
            }
            if (Result == "" && Client.Connected)
            {
                IsConnected = true;
                //log
                LogHelper.LogWrite($"MB连接成功，返回值:{Result}");
                timerCheck.Enabled = true;
                return true;
            }
            else
            {
                IsConnected = false;
                //log
                LogHelper.LogWrite($"MB连接失败，返回值:{Result}");
                timerCheck.Enabled = true;
                return false;
            }

        }

        public bool Close()
        {
            var Result = "";
            try
            {
                Client.Disconnect();
            }
            catch (Exception ex)
            {
                Result = ex.ToString(); 
            }
            if (Result == "")
            {
                IsConnected = false;
				//log
				LogHelper.LogWrite($"MB关闭连接成功，返回值:{Result}");
				return true;
            }
            else
            {
                IsConnected = false;
				LogHelper.LogWrite($"MB关闭连接失败，返回值:{Result}");
				//log
				return false;
            }
        }

        public void Dispose()
        {

            try
            {
                Client.Disconnect();
                //log
            }
            catch (Exception ex)
            {
                //log
            }
            
        }

        /// <summary>
        /// 写入方法
        /// </summary>
        /// <param name="writePara"></param>
        /// <returns></returns>
		public int Write(WritePara writePara)
        {
            //var t1 = DateTime.Now;
            int reCode = 0;
            //JObject valueJson = JObject.Parse(writePara);
            var srcValue = writePara.Value; //valueJson[propertyName: "Value"].ToString();
            var writeAddress = writePara.WriteAddress;//valueJson[propertyName: "WriteAddress"].ToString();
            var dataType = writePara.DataType;//short.Parse(valueJson[propertyName: "DataType"].ToString());
            //var groupName = writePara.GroupName; //valueJson[propertyName: "GroupName"].ToString();
            //var windex = writeAddress.IndexOf(".");
            //writeAddress = writeAddress.Remove(windex, 1).Insert(windex, ",");
            //var array = writeAddress.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            //var DBNum_string = array[0].ToString();
            //var DBNum = int.Parse(Regex.Replace(DBNum_string, "[a-z]", "", RegexOptions.IgnoreCase));

            var address = writeAddress;
            string startaddress = Regex.Replace(address, "[a-z]", "", RegexOptions.IgnoreCase);

            int address_dem = 0;
            int address_int = 0;
            if (startaddress.Contains(".") && startaddress.Length > 2)
            {
                try
                {
                    string[] address_arr = startaddress.Split('.');
                    address_int = int.Parse(address_arr[0]);
                    address_dem = int.Parse(address_arr[1]);
                }
                catch (Exception exp)
                {
                    //logger
                    LogHelper.LogWrite("MB写入数据出错，分离浮点的起始地址和bit位置出错 Address：" + writeAddress.ToString() + ",ERROR：" + exp.ToString());
                }
            }
            else
            {
                address_int = int.Parse(startaddress);
            }

            //int start = int.Parse(startaddress);

            int[] revbuffer_w;// = new byte[maxreg + 2];
            decimal value = decimal.Parse(srcValue);
            lock (_lock)
            {
                if (dataType == (short)DataType.BOOL)
                {
                    var boolbyte = new int[2];
                    var rebooltempread = ReadHoldingRegisters(address_int, 1, ref boolbyte);//  ReadArea(132, DBNum, address_int, 1, 2, ref boolbyte);
                    byte lowByte = (byte)(boolbyte[0] & 0xFF);  // 低字节
                    byte highByte = (byte)((boolbyte[0] >> 8) & 0xFF); // 高字节
                    var writeintarray = new int[2] { lowByte, highByte };
                    Console.WriteLine(rebooltempread);
                    var writeint = 0;
                    if (address_dem<8)
                    {
                        var bytetemp = ConvertDecimalToBinary(lowByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(bytetemp[0], highByte);
                        //writeintarray[0] = writeint;
                    }
                    else
                    {
                        address_dem = address_dem - 8;
                        var bytetemp = ConvertDecimalToBinary(highByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(lowByte, bytetemp[0]);
                        //writeintarray[1] = writeint;
                    }
                    ushort combined = (ushort)((highByte << 8) | lowByte);
                    try
                    {
                        Client.WriteSingleRegister(address_int, writeint);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入布尔数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.FLOAT)
                {
                    var writeBuff = ModbusClient.ConvertFloatToRegisters((float)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入浮点数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.IFLOAT)
                {
                    var writeBuff = ModbusClient.ConvertFloatToRegisters((float)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入浮点数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.INT)
                {
                    var writeBuff = ModbusClient.ConvertIntToRegisters((int)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入整型数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.WORD)
                {
                    var writeBuff = ModbusClient.ConvertLongToRegisters((long)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入字数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.BYTE)
                {
                    var writeBuff = ModbusClient.ConvertIntToRegisters((int)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入字节数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.PBOOL)
                {
                    var boolbyte = new int[2];
                    var rebooltempread = ReadHoldingRegisters(address_int, 1, ref boolbyte);//  ReadArea(132, DBNum, address_int, 1, 2, ref boolbyte);
                    byte lowByte = (byte)(boolbyte[0] & 0xFF);  // 低字节
                    byte highByte = (byte)((boolbyte[0] >> 8) & 0xFF); // 高字节
                    var writeintarray = new int[2] { lowByte, highByte };
                    Console.WriteLine(rebooltempread);
                    var writeint = 0;
                    if (address_dem < 8)
                    {
                        var bytetemp = ConvertDecimalToBinary(lowByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(bytetemp[0], highByte);
                        //writeintarray[0] = writeint;
                    }
                    else
                    {
                        address_dem = address_dem - 8;
                        var bytetemp = ConvertDecimalToBinary(highByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(lowByte, bytetemp[0]);
                        //writeintarray[1] = writeint;
                    }
                    ushort combined = (ushort)((highByte << 8) | lowByte);
                    try
                    {
                        Client.WriteSingleRegister(address_int, writeint);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入P布尔数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else
                {

                }
            }
            Console.WriteLine(writePara);
            //var t2 = DateTime.Now;
            //var timediff = t2 - t1;
            //Console.WriteLine($"S7写入耗时：{timediff}");
            return reCode;
        }

        public int WriteBlock(WriteBlockPara writePara)
        {
            //var t1 = DateTime.Now;
            int reCode = 0;
            //JObject valueJson = JObject.Parse(writePara);
            var srcValue = writePara.Value; //valueJson[propertyName: "Value"].ToString();
            var writeAddress = writePara.WriteAddress;//valueJson[propertyName: "WriteAddress"].ToString();
            var dataType = writePara.DataType;//short.Parse(valueJson[propertyName: "DataType"].ToString());
            var windex = writeAddress.IndexOf(".");
            writeAddress = writeAddress.Remove(windex, 1).Insert(windex, ",");
            var array = writeAddress.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var DBNum_string = array[0].ToString();
            var DBNum = int.Parse(Regex.Replace(DBNum_string, "[a-z]", "", RegexOptions.IgnoreCase));

            var address = array[1].ToString();
            string startaddress = Regex.Replace(address, "[a-z]", "", RegexOptions.IgnoreCase);
            int address_dem = 0;
            int address_int = 0;
            if (startaddress.Contains(".") && startaddress.Length > 2)
            {
                try
                {
                    string[] address_arr = startaddress.Split('.');
                    address_int = int.Parse(address_arr[0]);
                    address_dem = int.Parse(address_arr[1]);
                }
                catch (Exception exp)
                {
                    //logger
                    LogHelper.LogWrite("S7写入数据出错，分离浮点的起始地址和bit位置出错 Address：" + writeAddress.ToString() + ",ERROR：" + exp.ToString());
                }
            }
            else
            {
                address_int = int.Parse(startaddress);
            }

            byte[] revbuffer_w;// = new byte[maxreg + 2];
            decimal value = decimal.Parse(srcValue);
            lock (_lock)
            {
                if (dataType == (short)DataType.BOOL)
                {
                    var boolbyte = new int[2];
                    var rebooltempread = ReadHoldingRegisters(address_int, 1, ref boolbyte);//  ReadArea(132, DBNum, address_int, 1, 2, ref boolbyte);
                    byte lowByte = (byte)(boolbyte[0] & 0xFF);  // 低字节
                    byte highByte = (byte)((boolbyte[0] >> 8) & 0xFF); // 高字节
                    var writeintarray = new int[2] { lowByte, highByte };
                    Console.WriteLine(rebooltempread);
                    var writeint = 0;
                    if (address_dem < 8)
                    {
                        var bytetemp = ConvertDecimalToBinary(lowByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(bytetemp[0], highByte);
                        //writeintarray[0] = writeint;
                    }
                    else
                    {
                        address_dem = address_dem - 8;
                        var bytetemp = ConvertDecimalToBinary(highByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(lowByte, bytetemp[0]);
                        //writeintarray[1] = writeint;
                    }
                    ushort combined = (ushort)((highByte << 8) | lowByte);
                    try
                    {
                        Client.WriteSingleRegister(address_int, writeint);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入布尔数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.FLOAT)
                {
                    var writeBuff = ModbusClient.ConvertFloatToRegisters((float)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入浮点数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.IFLOAT)
                {
                    var writeBuff = ModbusClient.ConvertFloatToRegisters((float)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入浮点数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.INT)
                {
                    var writeBuff = ModbusClient.ConvertIntToRegisters((int)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入整型数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.WORD)
                {
                    var writeBuff = ModbusClient.ConvertLongToRegisters((long)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入字数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.BYTE)
                {
                    var writeBuff = ModbusClient.ConvertIntToRegisters((int)value);
                    try
                    {
                        Client.WriteMultipleRegisters(address_int, writeBuff);//.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入字节数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else if (dataType == (short)DataType.PBOOL)
                {
                    var boolbyte = new int[2];
                    var rebooltempread = ReadHoldingRegisters(address_int, 1, ref boolbyte);//  ReadArea(132, DBNum, address_int, 1, 2, ref boolbyte);
                    byte lowByte = (byte)(boolbyte[0] & 0xFF);  // 低字节
                    byte highByte = (byte)((boolbyte[0] >> 8) & 0xFF); // 高字节
                    var writeintarray = new int[2] { lowByte, highByte };
                    Console.WriteLine(rebooltempread);
                    var writeint = 0;
                    if (address_dem < 8)
                    {
                        var bytetemp = ConvertDecimalToBinary(lowByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(bytetemp[0], highByte);
                        //writeintarray[0] = writeint;
                    }
                    else
                    {
                        address_dem = address_dem - 8;
                        var bytetemp = ConvertDecimalToBinary(highByte);
                        Thread.Sleep(10);
                        var temval = (float)value;
                        bool bl = temval > 0.0f ? true : false;
                        //var rtbyte = revbuffer_w[address_int];
                        //var rtbuff = Sharp7.S7. rtbyte
                        SetBitAt(ref bytetemp, 0, address_dem, bl);
                        writeint = ConvertBinaryToInt(lowByte, bytetemp[0]);
                        //writeintarray[1] = writeint;
                    }
                    ushort combined = (ushort)((highByte << 8) | lowByte);
                    try
                    {
                        Client.WriteSingleRegister(address_int, writeint);
                    }
                    catch (Exception ex)
                    {
                        reCode = -1;
                        LogHelper.LogWrite($"{DriverName}的modbus写入数据出错，写入P布尔数据出错 Address：" + writeAddress.ToString() + ",ERROR：" + ex.ToString());
                    }
                }
                else
                {

                }
            }
            Console.WriteLine(writePara);
            //var t2 = DateTime.Now;
            //var timediff = t2 - t1;
            //Console.WriteLine($"S7写入耗时：{timediff}");
            return reCode;
        }
        public byte[] ConvertDecimalToBinary(int decimalNumber)
        {
            // 计算需要多少个字节来表示这个数
            int byteCount = (int)Math.Ceiling(Math.Log(decimalNumber + 1, 2) / 8.0);

            // 确保至少有一个字节，即使输入是0
            byteCount = Math.Max(byteCount, 1);

            byte[] binary = new byte[byteCount];

            for (int i = 0; i < byteCount; i++)
            {
                // 从低位到高位填充字节
                binary[i] = (byte)(decimalNumber >> (8 * i) & 0xFF);
            }

            // 反转数组，因为我们是从低位开始填充的
            Array.Reverse(binary);

            return binary;
        }
        public int ConvertBinaryToInt(byte lowByte, byte highByte)
        {
            ushort combined = (ushort)((highByte << 8) | lowByte);

            return combined;
        }
        public static void SetBitAt(ref byte[] Buffer, int Pos, int Bit, bool Value)
        {
            byte[] Mask = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
            if (Bit < 0) Bit = 0;
            if (Bit > 7) Bit = 7;

            if (Value)
                Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]);
            else
                Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]);
        }
        /*
/// <summary>
/// 写入方法
/// </summary>
/// <param name="writePara"></param>
/// <returns></returns>
public int Write(string writePara)
{
  int reCode = 0;
  JObject valueJson = JObject.Parse(writePara);
  var srcValue = valueJson[propertyName: "Value"].ToString();
  var writeAddress = valueJson[propertyName: "WriteAddress"].ToString();
  var dataType =short.Parse(valueJson[propertyName: "DataType"].ToString());
  var groupName = valueJson[propertyName: "GroupName"].ToString();

  var array = writeAddress.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  var DBNum_string = array[0].ToString();
  var DBNum = int.Parse(Regex.Replace(DBNum_string, "[a-z]", "", RegexOptions.IgnoreCase));

  var address = array[1].ToString();
  string startaddress = Regex.Replace(address, "[a-z]", "", RegexOptions.IgnoreCase);
  int address_dem = 0;
  int address_int = 0;
  if (startaddress.Contains(".") && startaddress.Length > 2)
  {
      try
      {
          string[] address_arr = startaddress.Split('.');
          address_int = int.Parse(address_arr[0]);
          address_dem = int.Parse(address_arr[1]);
      }
      catch (Exception exp)
      {
          //logger
      }
  }
  else
  {
      address_int = int.Parse(startaddress);
  }

  byte[] revbuffer_w;// = new byte[maxreg + 2];
  decimal value = decimal.Parse(srcValue);
  lock (_lock)
  {
      if (dataType == (short)DataType.BOOL)
      {
          var boolbyte = new byte[1];
          int rebooltempread = ReadHoldingRegisters(132, DBNum, address_int, 1, 2, ref boolbyte);
          Thread.Sleep(50);
          Console.WriteLine(rebooltempread);
          var temval = (float)value;
          bool bl = temval > 0.0f ? true : false;
          //var rtbyte = revbuffer_w[address_int];
          //var rtbuff = Sharp7.S7. rtbyte
          Sharp7.S7.SetBitAt(ref boolbyte, 0, address_dem, bl);
          reCode = Client.WriteArea(132, DBNum, address_int, 1, 2, boolbyte);
      }
      else if (dataType == (short)DataType.FLOAT)
      {
          revbuffer_w = new byte[4];
          Sharp7.S7.SetRealAt(revbuffer_w, 0, (float)value);
          reCode = Client.WriteArea(132, DBNum, address_int, 4, 2, revbuffer_w);
      }
      else if (dataType == (short)DataType.WORD)
      {
          revbuffer_w = new byte[2];
          Sharp7.S7.SetWordAt(revbuffer_w, 0, (ushort)value);
          reCode = Client.WriteArea(132, DBNum, address_int, 2, 2, revbuffer_w);
      }
      else if (dataType == (short)DataType.BYTE)
      {
          revbuffer_w = new byte[1];
          Sharp7.S7.SetByteAt(revbuffer_w, 0, (byte)value);
          reCode = Client.WriteArea(132, DBNum, address_int, 1, 2, revbuffer_w);
      }
      else
      {

      }
  }
  Console.WriteLine(writePara);
  return reCode;
}
*/
    }
}
