using CCDCount.DLL.AlarmTools;
using CCDCount.DLL.Tools;
using CCDCount.MODEL.PlcModel;
using iTextSharp.text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace CCDCount.DLL
{
    public class PLCManagementClass
    {
        private bool isConnect = false;
        public bool IsConnect
        {
            get
            {
                return isConnect?modbusTcpClient.IsTcpClientConnected():isConnect;
            }
        }


        public ModbusTcpClient modbusTcpClient = new ModbusTcpClient();
        public PLCManagementClass(string ipAddress)
        {
            ConnectModbus(ipAddress);
        }

        public void ConnectModbus(string ipAddress)
        {
            if (!modbusTcpClient.Connect(ipAddress))
            {
                //FaultLog.RecordErrorMessage($"Modbus通讯连接失败,目标IP:{ipAddress}");
                SystemAlarm.AlarmAlert(AlarmMessageList.PLC通讯连接失败, $"Modbus通讯连接失败,目标IP:{ipAddress}", "DLL:PLCManagementClass-ConnectModbus");
                isConnect = false;
                return;
            }
            isConnect = true;
            SystemAlarm.AlarmCancel(AlarmMessageList.PLC通讯连接失败);
        }

        /****************************************************动作操作*****************************************************************/

                    
        ushort Mask1 = (ushort)(1 << 0);
        ushort Mask2 = (ushort)(1 << 8);
        /// <summary>
        /// 切换闸门点动
        /// </summary>
        /// <param name="value">闸门编号</param>
        public bool SwitchValveManualControl(int value)
        {
            bool result = false;
            if (value >= 0 && value <= 7)
            {
                var readmessage = modbusTcpClient.ReadHoldingRegisters(1, 400, 4, out ushort[] returnvalue);
                ushort sendmessage = returnvalue[value / 2];
                if (value % 2 == 0)
                {
                    sendmessage = (ushort)(sendmessage ^ Mask1);
                }
                else
                {
                    sendmessage = (ushort)(sendmessage ^ Mask2);
                }
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: (ushort)(400 + (value / 2)), value: sendmessage);
            }
            return result;
        }
        /// <summary>
        /// 传动轴运动切换
        /// </summary>
        /// <returns></returns>
        public bool SwitchScrewManualControl()
        {
            bool result = false;
            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 501, 1, out ushort[] returnvalue);
            ushort sendMessage = (ushort)(returnvalue[0] ^ Mask1);
            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 501, value: sendMessage);
            return result;
        }

        /// <summary>
        /// 传动轴回原点
        /// </summary>
        /// <returns></returns>
        public bool ScrewHomeToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 505, value: 1);
            return result;
        }

        public bool ScrewJogFwdToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 509, value: 1);
            return result;
        }

        public bool ScrewJogFwdToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 509, value: 0);
            return result;
        }

        public bool ScrewJogRevToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 513, value: 1);
            return result;
        }

        public bool ScrewJogRevToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 513, value: 0);
            return result;
        }

        public bool FillingValveManualOpenToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 517, value: 1);
            return result;
        }
        public bool FillingValveManualOpenToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 517, value: 0);
            return result;
        }
        public bool FillingValveManualCloseToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 521, value: 1);
            return result;
        }
        public bool FillingValveManualCloseToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 521, value: 0);
            return result;
        }
        public bool FillingValveManualCache()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 525, value: 1);
            return result;
        }
        public bool FillingValveJogFwdToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 529, value: 1);
            return result;
        }

        public bool FillingValveJogFwdToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 529, value: 0);
            return result;
        }
        public bool FillingValveJogRevToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 533, value: 1);
            return result;
        }

        public bool FillingValveJogRevToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 533, value: 0);
            return result;
        }

        public bool FillingValveHomeToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 537, value: 1);
            return result;
        }

        public bool BeltsJogToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 541, value: 1);
            return result;
        }

        public bool BeltsJogToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 541, value: 0);
            return result;
        }

        public bool ShakeTableJogToTrue()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 545, value: 1);
            return result;
        }

        public bool ShakeTableJogToFalse()
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 545, value: 0);
            return result;
        }

        /// <summary>
        /// 启动设置为True
        /// </summary>
        public bool MachineRunToTrue()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(1 << 0);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        /// <summary>
        /// 启动设置为False
        /// </summary>
        public bool MachineRunToFalse()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(0 << 0);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        /// <summary>
        /// 停止设置为True
        /// </summary>
        public bool MachineStopToTrue()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(1 << 1);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        /// <summary>
        /// 停止设置为False
        /// </summary>
        public bool MachineStopToFalse()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(0 << 1);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        /// <summary>
        /// 设备上升
        /// </summary>
        public bool MachineManualUpToTrue()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(1 << 2);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        public bool MachineManualUpToFalse()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort mask = 0b1111111111111011;
                ushort SendMessage = (ushort)(returnValue[0] & mask);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }


        /// <summary>
        /// 设备下降
        /// </summary>
        public bool MachineManualDownToTrue()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(1 << 3);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        public bool MachineManualDownToFalse()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort mask = 0b1111111111110111;
                ushort SendMessage = (ushort)(returnValue[0] & mask);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        /// <summary>
        /// 漏斗状态切换
        /// </summary>
        /// <returns></returns>
        public bool SwitchFunnelValveManualControl()
        {
            bool result = false;
            ushort mask = (ushort)(1 << 4);
            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 1014, 1, out ushort[] returnvalue);
            ushort sendMessage = (ushort)(returnvalue[0] ^ mask);
            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: sendMessage);
            return result;
        }
        /// <summary>
        /// 传送带运行状态切换
        /// </summary>
        /// <returns></returns>
        public bool SwitchMachineManualControl()
        {
            bool result = false;
            ushort mask = (ushort)(1 << 5);
            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 1014, 1, out ushort[] returnvalue);
            ushort sendMessage = (ushort)(returnvalue[0] ^ mask);
            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: sendMessage);
            return result;
        }
        /// <summary>
        /// 切换气锁状态
        /// </summary>
        /// <returns></returns>
        public bool SwitchMachineAirLockValve()
        {
            bool result = false;
            ushort mask = (ushort)(1 << 6);
            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 1014, 1, out ushort[] returnvalue);
            ushort sendMessage = (ushort)(returnvalue[0] ^ mask);
            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: sendMessage);
            return result;
        }

        /// <summary>
        /// 震台手动开关
        /// </summary>
        /// <returns></returns>
        public bool SwitchShakeTable_Test()
        {
            bool result = false;
            ushort mask = (ushort)(1 << 7);
            var readMessage = modbusTcpClient.ReadHoldingRegisters(1, 1014, 1, out ushort[] returnvalue);
            ushort sendMessage = (ushort)(returnvalue[0] ^ mask);
            result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: sendMessage);
            return result;
        }

        /// <summary>
        /// 数据清零
        /// </summary>
        public bool DataResetToTrue()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort SendMessage = returnValue[0];
                SendMessage |= (ushort)(1 << 8);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        public bool DataResetToFalse()
        {
            bool result = false;
            modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 1014, numRegisters: 1, out ushort[] returnValue);
            if (returnValue != null)
            {
                ushort mask = 0b1111111011111111;
                ushort SendMessage = (ushort)(returnValue[0] & mask);
                result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 1014, value: SendMessage);
            }
            return result;
        }

        /*********************************************参数操作***************************************************************/

        /// <summary>
        /// 写入罐装模式
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteFillingMode(ushort Value)
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 2000, value: Value);
            return result;
        }

        /// <summary>
        /// 写入传送带速度
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteBeltsSpeed(ushort Value)
        {
            bool result = modbusTcpClient.WriteSingleRegister(slaveId: 1, registerAddress: 2008, value: Value);
            return result;
        }


        /// <summary>
        /// 写入罐装料筒震台高速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable1H_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3000, Value);
        }

        /// <summary>
        /// 写入罐装过滤震台高速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable2H_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3024, Value);
        }

        /// <summary>
        /// 写入罐装计数震台高速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable3H_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3048, Value);
        }

        /// <summary>
        /// 写入罐装料筒震台减速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable1M_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3008, Value);
        }

        /// <summary>
        /// 写入罐装过滤震台减速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable2M_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3032, Value);
        }

        /// <summary>
        /// 写入罐装计数震台减速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable3M_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3056, Value);
        }

        /// <summary>
        /// 写入罐装料筒震台低速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable1L_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3016, Value);
        }

        /// <summary>
        /// 写入罐装过滤震台低速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable2L_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3040, Value);
        }

        /// <summary>
        /// 写入罐装计数震台低速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable3L_FillingSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3064, Value);
        }

        /// <summary>
        /// 写入缓存料筒震台高速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable1H_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3072, Value);
        }

        /// <summary>
        /// 写入缓存过滤震台高速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable2H_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3096, Value);
        }

        /// <summary>
        /// 写入缓存计数震台高速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable3H_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3120, Value);
        }

        /// <summary>
        /// 写入缓存料筒震台减速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable1M_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3080, Value);
        }

        /// <summary>
        /// 写入缓存过滤震台减速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable2M_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3104, Value);
        }

        /// <summary>
        /// 写入缓存计数震台减速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable3M_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3128, Value);
        }

        /// <summary>
        /// 写入缓存料筒震台低速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable1L_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3088, Value);
        }

        /// <summary>
        /// 写入缓存过滤震台低速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable2L_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3112, Value);
        }

        /// <summary>
        /// 写入缓存计数震台低速值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteShakeTable3L_CacheSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3136, Value);
        }

        /// <summary>
        /// 写入罐装高速区间
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingH_SpeedRatio(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3144, Value);
        }

        /// <summary>
        /// 写入罐装减速区间
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingM_SpeedRatio(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3152, Value);
        }

        /// <summary>
        /// 写入罐装低速区间
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingL_SpeedRatio(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3160, Value);
        }

        /// <summary>
        /// 写入缓存高速区间
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteCacheH_SpeedRatio(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3168, Value);
        }

        /// <summary>
        /// 写入缓存减速区间
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteCacheM_SpeedRatio(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3176, Value);
        }

        /// <summary>
        /// 写入缓存低速区间
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteCacheL_SpeedRatio(ushort Value)
        {
            bool result = modbusTcpClient.WriteSingleRegister(1, 3184, Value);
            return result;
        }


        /// <summary>
        /// 写入传动轴点动速度
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteScrewJogSpeed(double Value)
        {
            bool result = modbusTcpClient.WriteSingleLReal(slaveId: 1, startAddress: 3192, value: Value);
            return result;
        }

        /// <summary>
        /// 写入进瓶速度
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteInBottleSpeed(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(slaveId: 1, startAddress: 3224, value: Value);
        }


        /// <summary>
        /// 写入中转阀打开速度
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteBottlePosSpeed(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3256, Value);
        }

        /// <summary>
        /// 写入中转阀打开位置
        /// </summary>
        public bool WriteBottlePosPosition(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3288, Value);
        }

        /// <summary>
        /// 写入中转阀打开速度
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingValveOpenSpeed(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3320, Value);
        }

        /// <summary>
        /// 写入中转阀打开位置
        /// </summary>
        public bool WriteFillingValveOpenPosition(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3352, Value);
        }

        /// <summary>
        /// 写入中转阀关闭速度
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingValveCloseSpeed(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3384, Value);
        }

        /// <summary>
        /// 写入中转阀关位置
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingValveClosePosition(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3416, Value);
        }

        /// <summary>
        /// 写入中转阀缓存速度
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteFillingValveCacheSpeed(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3448, Value);
        }
        /// <summary>
        /// 写入中转阀缓存位置
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteFillingValveCachePosition(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3480, Value);
        }
        /// <summary>
        /// 写入中转阀点动速度
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteFillingValveJogSpeed(double Value)
        {
            return modbusTcpClient.WriteSingleLReal(1, 3512, Value);
        }
        /// <summary>
        /// 写入漏斗下降延时
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteMachineDelayFunneDownTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3544, Value);
        }
        /// <summary>
        /// 写入漏斗上升延时
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteMachineDelayFunneUpTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3560, Value);
        }
        /// <summary>
        /// 写入中转阀开启延时
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteMachineDelayFillingValveOpenTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3576, Value);
        }
        /// <summary>
        /// 写入中转阀关闭延时
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteMachineDelayFillingValveCloseTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3592, Value);
        }
        /// <summary>
        /// 写入进瓶延时
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteMachineDelayInBottleTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3608, Value);
        }
        /// <summary>
        /// 写入空气阀开启延时
        /// </summary>
        public bool WriteValveDelytime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3624, Value);
        }
        /// <summary>
        /// 写入缺瓶检测时间
        /// </summary>
        public bool WriteMissingDelaytime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3642, Value);
        }
        /// <summary>
        /// 写入堵瓶检测时间
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteBottleJamDelaytime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3644, Value);
        }
        /// <summary>
        /// 写入剔废气缸延时时间
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteEliminateCylinderDelayTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3658, Value);
        }
        /// <summary>
        /// 写入剔废气缸保持时间
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteEliminateCylinderHoldingTime(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3660, Value);
        }

        /// <summary>
        /// 写入料筒震台测试速度
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteShakeTable1_TestSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3652, Value);
        }
        /// <summary>
        /// 写入料筒震台测试速度
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteShakeTable2_TestSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3654, Value);
        }
        /// <summary>
        /// 写入料筒震台测试速度
        /// </summary>
        /// <param name="Value"></param>
        /// <returns></returns>
        public bool WriteShakeTable3_TestSpeed(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 3656, Value);
        }
        /// <summary>
        /// 写入罐装设定值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteBottValueSet(UInt16 Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 2504, Value);
        }

        /// <summary>
        /// 写入缓存停机值
        /// </summary>
        /// <param name="Value"></param>
        public bool WriteCacheShutdownValue(ushort Value)
        {
            return modbusTcpClient.WriteSingleRegister(1, 2505, Value);
        }
        /// <summary>
        /// 读取所有参数(参数数据表)
        /// </summary>
        public PlcParaModelClass ReadAllPara()
        {
            PlcParaModelClass result = null;
            var results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3000, numRegisters: 120, out ushort[] ReturnValue);
            if (!results || ReturnValue == null) return null;
            result = new PlcParaModelClass()
            {
                ShakeTable1H_FillingSpeed = ReturnValue[0],
                ShakeTable2H_FillingSpeed = ReturnValue[24],
                ShakeTable3H_FillingSpeed = ReturnValue[48],
                ShakeTable1M_FillingSpeed = ReturnValue[8],
                ShakeTable2M_FillingSpeed = ReturnValue[32],
                ShakeTable3M_FillingSpeed = ReturnValue[56],
                ShakeTable1L_FillingSpeed = ReturnValue[16],
                ShakeTable2L_FillingSpeed = ReturnValue[40],
                ShakeTable3L_FillingSpeed = ReturnValue[64],
                ShakeTable1H_CacheSpeed = ReturnValue[72],
                ShakeTable1M_CacheSpeed = ReturnValue[80],
                ShakeTable1L_CacheSpeed = ReturnValue[88],
                ShakeTable2H_CacheSpeed = ReturnValue[96],
                ShakeTable2M_CacheSpeed = ReturnValue[104],
                ShakeTable2L_CacheSpeed = ReturnValue[112]
            };
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3120, numRegisters: 108, out ReturnValue);
            if (!results || ReturnValue == null) return null;
            result.ShakeTable3H_CacheSpeed = ReturnValue[0];
            result.ShakeTable3M_CacheSpeed = ReturnValue[8];
            result.ShakeTable3L_CacheSpeed = ReturnValue[16];
            result.FillingH_SpeedRatio = ReturnValue[24];
            result.FillingM_SpeedRatio = ReturnValue[32];
            result.FillingL_SpeedRatio = ReturnValue[40];
            result.CacheH_SpeedRatio = ReturnValue[48];
            result.CacheM_SpeedRatio = ReturnValue[56];
            result.CacheL_SpeedRatio = ReturnValue[64];
            result.ScrewJogSpeed = GetDoubleFromRegisters(ReturnValue.Skip(72).Take(4).ToArray());
            result.InBottleSpeed = GetDoubleFromRegisters(ReturnValue.Skip(104).Take(4).ToArray());
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3256, numRegisters: 100, out ReturnValue);
            if (!results || ReturnValue == null) return null;
            result.BottlePosSpeed = GetDoubleFromRegisters(ReturnValue.Take(4).ToArray());
            result.BottlePosPosition = GetDoubleFromRegisters(ReturnValue.Skip(32).Take(4).ToArray());
            result.FillingValveOpenSpeed = GetDoubleFromRegisters(ReturnValue.Skip(64).Take(4).ToArray());
            result.FillingValveOpenPosition = GetDoubleFromRegisters(ReturnValue.Skip(96).Take(4).ToArray());
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3384, numRegisters: 100, out ReturnValue);
            if (!results || ReturnValue == null) return null;
            result.FillingValveCloseSpeed = GetDoubleFromRegisters(ReturnValue.Take(4).ToArray());
            result.FillingValveClosePosition = GetDoubleFromRegisters(ReturnValue.Skip(32).ToArray());
            result.FillingValveCacheSpeed = GetDoubleFromRegisters(ReturnValue.Skip(64).Take(4).ToArray());
            result.FillingValueCachePosition = GetDoubleFromRegisters(ReturnValue.Skip(96).Take(4).ToArray());
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3512, numRegisters: 116, out ReturnValue);
            if (!results || ReturnValue == null) return null;
            result.FillingValueJogSpeed = GetDoubleFromRegisters(ReturnValue.Take(4).ToArray());
            result.MachineDelayFunneDownTime = ReturnValue[32];
            result.MachineDelayFunneUpTime = ReturnValue[48];
            result.MachineDelayFillingValveOpenTime = ReturnValue[64];
            result.MachineDelayFillingValveCloseTime = ReturnValue[80];
            result.MachineDelayInBottleTime = ReturnValue[96];
            result.ValveDelytime = ReturnValue[112];
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3642, numRegisters: 20, out ReturnValue);
            result.MissingDelaytime = ReturnValue[0];
            result.BottleJamDelaytime = ReturnValue[2];
            result.ShakeTable1_TestSpeed = ReturnValue[10];
            result.ShakeTable2_TestSpeed = ReturnValue[12];
            result.ShakeTable3_TestSpeed = ReturnValue[14];
            result.EliminateCylinderDelayTime = ReturnValue[16];
            result.EliminateCylinderHoldingTime = ReturnValue[18];
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 2504, numRegisters: 2, out ReturnValue);
            if (!results || ReturnValue == null) return null;
            result.BottValueSet = ReturnValue[0];
            result.CacheShutdownValue = ReturnValue[1];
            results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 2000, numRegisters: 16, out ReturnValue);
            if (!results || ReturnValue == null) return null;
            result.FillingMode = ReturnValue[0];
            result.BeltsSpeed = ReturnValue[8];
            return result;
        }
        /*********************************************批次记录用数据***************************************************************/

        public bool ReadBottingVibrationTableHighSpeedValue(out ushort ShakeTable1H_FillingSpeed, out ushort ShakeTable2H_FillingSpeed, out ushort ShakeTable3H_FillingSpeed)
        {
            bool result = false;
            var results = modbusTcpClient.ReadHoldingRegisters(slaveId: 1, startAddress: 3000, numRegisters: 48, out ushort[] ReturnValue);
            if (!results || ReturnValue == null)
            {
                ShakeTable1H_FillingSpeed = 0;
                ShakeTable2H_FillingSpeed = 0;
                ShakeTable3H_FillingSpeed = 0;
                return result;
            }
            ShakeTable1H_FillingSpeed = ReturnValue[0];
            ShakeTable2H_FillingSpeed = ReturnValue[24];
            ShakeTable3H_FillingSpeed = ReturnValue[48];
            return result;
        }

        public int BottingSpeed { 
            get
            {
                return BottTimeList[BottTimeList.Count - 1].bottnum - (BottTimeList.Where(o => (DateTime.Now - o.BootTime).TotalSeconds > 1).Max(o => o.bottnum));
            }
        }
        List<(int bottnum, DateTime BootTime)> BottTimeList = new List<(int, DateTime)>();

        public bool ReadBottingCount(out ushort Count)
        {
            bool result = false;
            if(modbusTcpClient.ReadHoldingRegisters(1, 3650, 1,out ushort[] ReturnValue))//临时地址
            {
                Count = ReturnValue[0];
                result = true;
            }
            else
            {
                Count = 0;
            }
            for (int i = BottTimeList.Count-1;i>0;i--)
            {
                if ((DateTime.Now - BottTimeList[i].BootTime).TotalSeconds>2)
                {
                    BottTimeList.Remove(BottTimeList[i]);
                }
            }
            if(result)
            {
                BottTimeList.Add((Count, DateTime.Now));
            }
            return result;
        }

        /*********************************************心跳用数据***************************************************************/

        public bool HeartMessage()
        {
            return modbusTcpClient.WriteSingleRegister(1, 561, 1);
        }

        /// <summary>
        /// 获取16位寄存器中的32Uint位值
        /// </summary>
        private UInt32 GetInt32FromRegisters(ushort[] registers,string byteOrder = "BADC")
        {
            ushort highRegister = registers[0];
            ushort lowRegister = registers[1];

            byte[] bytes = ConvertToByteArray(lowRegister, highRegister, byteOrder);

            // 转换为float
            return (UInt32)BitConverter.ToInt32(bytes, 0);
        }

        /// <summary>
        /// 获取16位寄存器中的32Float位值
        /// </summary>
        private float GetFloatFromRegisters(ushort[] registers)
        {
            string byteOrder = "BADC";
            ushort highRegister = registers[0];
            ushort lowRegister = registers[1];
            byte[] bytes = ConvertToByteArray(lowRegister, highRegister, byteOrder);
            return BitConverter.ToSingle(bytes, 0); ;
        }
        
        /// <summary>
        /// 获取寄存器中的64位Double值
        /// </summary>
        /// <param name="registers"></param>
        /// <param name="byteOder"></param>
        /// <returns></returns>
        private double GetDoubleFromRegisters(ushort[] registers,string byteOder="BADC")
        {
            ushort reg1 = registers[0];
            ushort reg2 = registers[1];
            ushort reg3 = registers[2];
            ushort reg4 = registers[3];

            byte[] bytes = ConvertToByteArray8Bytes(reg1, reg2, reg3, reg4, byteOder);

            return BitConverter.ToDouble(bytes, 0);
        }

        /// <summary>
        /// 将寄存器数组换为字节数组转（根据指定字节序）
        /// </summary>
        /// <param name="lowRegister">低位寄存器</param>
        /// <param name="highRegister">高位寄存器</param>
        /// <param name="byteOrder">字节序</param>
        /// <returns>字节数组</returns>
        private byte[] ConvertToByteArray(ushort lowRegister, ushort highRegister, string byteOrder = "BADC")
        {
            byte[] bytes = new byte[4];

            switch (byteOrder.ToUpper())
            {
                case "ABCD": // 大端序
                    bytes[0] = (byte)(highRegister >> 8);
                    bytes[1] = (byte)(highRegister & 0xFF);
                    bytes[2] = (byte)(lowRegister >> 8);
                    bytes[3] = (byte)(lowRegister & 0xFF);
                    break;
                case "CDAB": // 小端序
                    bytes[0] = (byte)(lowRegister >> 8);
                    bytes[1] = (byte)(lowRegister & 0xFF);
                    bytes[2] = (byte)(highRegister >> 8);
                    bytes[3] = (byte)(highRegister & 0xFF);
                    break;
                case "BADC":
                    bytes[0] = (byte)(highRegister & 0xFF);
                    bytes[1] = (byte)(highRegister >> 8);
                    bytes[2] = (byte)(lowRegister & 0xFF);
                    bytes[3] = (byte)(lowRegister >> 8);
                    break;
                case "DCBA":
                    bytes[0] = (byte)(lowRegister & 0xFF);
                    bytes[1] = (byte)(lowRegister >> 8);
                    bytes[2] = (byte)(highRegister & 0xFF);
                    bytes[3] = (byte)(highRegister >> 8);
                    break;
                default:
                    // 默认使用ABCD顺序
                    bytes[0] = (byte)(highRegister >> 8);
                    bytes[1] = (byte)(highRegister & 0xFF);
                    bytes[2] = (byte)(lowRegister >> 8);
                    bytes[3] = (byte)(lowRegister & 0xFF);
                    break;
            }
            return bytes;
        }

        /// <summary>
        /// 将寄存器数组转换为字节数组（根据指定字节序，用于8字节double值）
        /// </summary>
        /// <param name="reg1">第1个寄存器（最高位寄存器）</param>
        /// <param name="reg2">第2个寄存器</param>
        /// <param name="reg3">第3个寄存器</param>
        /// <param name="reg4">第4个寄存器（最低位寄存器）</param>
        /// <param name="byteOrder">字节序</param>
        /// <returns>字节数组</returns>
        private byte[] ConvertToByteArray8Bytes(ushort reg1, ushort reg2, ushort reg3, ushort reg4, string byteOrder)
        {
            byte[] bytes = new byte[8];

            switch (byteOrder.ToUpper())
            {
                case "ABCD": // 大端序 - 寄存器顺序：reg1-reg2-reg3-reg4，字节顺序：0-1-2-3-4-5-6-7
                    bytes[0] = (byte)(reg1 >> 8);  // reg1高位字节
                    bytes[1] = (byte)(reg1 & 0xFF); // reg1低位字节
                    bytes[2] = (byte)(reg2 >> 8);  // reg2高位字节
                    bytes[3] = (byte)(reg2 & 0xFF); // reg2低位字节
                    bytes[4] = (byte)(reg3 >> 8);  // reg3高位字节
                    bytes[5] = (byte)(reg3 & 0xFF); // reg3低位字节
                    bytes[6] = (byte)(reg4 >> 8);  // reg4高位字节
                    bytes[7] = (byte)(reg4 & 0xFF); // reg4低位字节
                    break;
                case "CDAB": // 交换32位字 - 寄存器顺序：reg3-reg4-reg1-reg2
                    bytes[0] = (byte)(reg3 >> 8);  // reg3高位字节
                    bytes[1] = (byte)(reg3 & 0xFF); // reg3低位字节
                    bytes[2] = (byte)(reg4 >> 8);  // reg4高位字节
                    bytes[3] = (byte)(reg4 & 0xFF); // reg4低位字节
                    bytes[4] = (byte)(reg1 >> 8);  // reg1高位字节
                    bytes[5] = (byte)(reg1 & 0xFF); // reg1低位字节
                    bytes[6] = (byte)(reg2 >> 8);  // reg2高位字节
                    bytes[7] = (byte)(reg2 & 0xFF); // reg2低位字节
                    break;
                case "BADC": // 交换字内字节 - 高位字节在前，低位字节在后
                    bytes[0] = (byte)(reg1 & 0xFF); // reg1低位字节
                    bytes[1] = (byte)(reg1 >> 8);   // reg1高位字节
                    bytes[2] = (byte)(reg2 & 0xFF); // reg2低位字节
                    bytes[3] = (byte)(reg2 >> 8);   // reg2高位字节
                    bytes[4] = (byte)(reg3 & 0xFF); // reg3低位字节
                    bytes[5] = (byte)(reg3 >> 8);   // reg3高位字节
                    bytes[6] = (byte)(reg4 & 0xFF); // reg4低位字节
                    bytes[7] = (byte)(reg4 >> 8);   // reg4高位字节
                    break;
                case "DCBA": // 完全反转 - 寄存器顺序：reg4-reg3-reg2-reg1
                    bytes[0] = (byte)(reg4 & 0xFF); // reg4低位字节
                    bytes[1] = (byte)(reg4 >> 8);   // reg4高位字节
                    bytes[2] = (byte)(reg3 & 0xFF); // reg3低位字节
                    bytes[3] = (byte)(reg3 >> 8);   // reg3高位字节
                    bytes[4] = (byte)(reg2 & 0xFF); // reg2低位字节
                    bytes[5] = (byte)(reg2 >> 8);   // reg2高位字节
                    bytes[6] = (byte)(reg1 & 0xFF); // reg1低位字节
                    bytes[7] = (byte)(reg1 >> 8);   // reg1高位字节
                    break;
                default:
                    // 默认使用ABCD顺序
                    bytes[0] = (byte)(reg1 >> 8);
                    bytes[1] = (byte)(reg1 & 0xFF);
                    bytes[2] = (byte)(reg2 >> 8);
                    bytes[3] = (byte)(reg2 & 0xFF);
                    bytes[4] = (byte)(reg3 >> 8);
                    bytes[5] = (byte)(reg3 & 0xFF);
                    bytes[6] = (byte)(reg4 >> 8);
                    bytes[7] = (byte)(reg4 & 0xFF);
                    break;
            }
            return bytes;
        }
    }
}
