//#define USE_STANDER_CONNECT
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Common;
using Modbus.Device;

namespace MoonControl
{
    #region 伺服电机---串口RTU通信
    /// <summary>
    /// 伺服电机---串口rtu通信
    /// </summary>
    public class MoonMotor
    {
        private const int MoonsHomeStatus = 0x1003;      //获取电机回零状态地址

        private const int MoonsPositionAddress = 0xE319;     //扭矩设定值   参数3-25
        private const int MoonsPositiveRotation = 0xE31B;    //设定正传限速度   参数3-27
        private const int MoonsReversingRotation = 0xE31C;   //设定反传限速度   参数3-28

        private const int MoonsCurrentSpeed = 0xF501;       //读取当前电机转动速度地址
        private const int MoonsmotorSpeed = 0x1504;         //读取当前扭矩（受力）大小地址

        public const int abs_Address = 0x6200;          //绝对模式
        public const int posH_Address = 0x6201;         //高位
        public const int posL_Address = 0x6202;          //低位
        public const int Speed_Address = 0x6203;        //速度
        public const int Acc_adsAddress = 0x6204;       //加速度
        public const int Dec_Address = 0x6205;          //减速度
        public const int Abs_triger_Address = 0x6002;   //动作触发  停止

        public const int Home_M_Address = 0x600A;        //回零模式
        public const int Home_Speed_H_adsAddress = 0x600F;   //高速度
        public const int Home_Speed_L_Address = 0x6010;      //低速度
        public const int Home_triger_Address = 0x6002;     //回零触发


        private string m_port = "";
        private int m_baudrate = 9600;
        private ModbusSerialMaster m_master;
        private SerialPort m_serial;

        private object loc = new object();
        Adb_Common adb = new Adb_Common();

        //public MoonMotor(string port, int baudrate = 115200)
        public MoonMotor(string port, int baudrate = 38400)
        {
            this.m_port = port;
            this.m_baudrate = baudrate;
        }

        /// <summary>
        /// 打开端口
        /// </summary>
        /// <returns></returns>
        public bool OpenPort()
        {
            lock (loc)
            {
                if (m_serial == null)
                    m_serial = new SerialPort(m_port, m_baudrate, Parity.None, 8, StopBits.One);

                try
                {
                    if (m_serial.IsOpen == false)
                        m_serial.Open();

                    if (this.m_master == null)
                        this.m_master = ModbusSerialMaster.CreateRtu(m_serial);

                    return m_serial.IsOpen;
                }
                catch (Exception ex)
                {
                    m_serial = null;
                    //将异常写入文件
                    FileWriter.WriteLog("电机端口打开异常:" + ex.Message);
                    adb.Able_COM(m_port, "0");
                    adb.Able_COM(m_port, "1");
                    if (m_serial == null)
                        m_serial = new SerialPort(m_port, m_baudrate, Parity.None, 8, StopBits.One);

                    try
                    {
                        if (m_serial.IsOpen == false)
                            m_serial.Open();

                        if (this.m_master == null)
                            this.m_master = ModbusSerialMaster.CreateRtu(m_serial);

                        return m_serial.IsOpen;
                    }
                    catch (Exception e)
                    {
                        m_serial = null;
                        //将异常写入文件
                        FileWriter.WriteLog("电机端口打开异常:" + e.Message);
                        return false;
                    }
                    return false;
                }
            }
        }
        /// <summary>
        /// 关闭端口
        /// </summary>
        public void Close()
        {
            lock (loc)
            {
                try
                {
                    if (m_serial != null)
                    {
                        FileWriter.WriteLog("关闭端口");
                        m_serial.Close();
                    }
                       
                }
                catch(Exception ex)
                {
                    FileWriter.WriteLog(string.Format("Close fail  Exception:{0}", ex.Message));
                }
            }           
        }
        
        
        /// <summary>
        /// 设置电机参数，并立即运行
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsPosition(byte slave, ushort para)
        {
            lock (loc)
            {
                try
                {
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    this.m_master.WriteSingleRegister(slave, MoonsPositionAddress, para);
                    Thread.Sleep(10);
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("SetMoonsPosition exception:" + ex.Message);
                    return false;
                }
            }
        }

        /// <summary>
        /// 设置电机参数，并立即运行
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsPosition1(byte slave,ushort addr,ushort para)
        {
            lock (loc)
            {
                try
                {
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    this.m_master.WriteSingleRegister(slave, addr, para);
                    Thread.Sleep(10);
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("SetMoonsPosition exception:" + ex.Message);
                    return false;
                }
            }
        }

        /// <summary>
        /// 设置正转速度上限
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsPositiveRotation(byte slave, int para)
        {
            lock (loc)
            {
                try
                {

                    IList<ushort> para_list = new List<ushort>();
                    ushort var1 = 0;
                    ushort var2 = 0;
                    this.IntToHex(para, out var1, out var2);
                    //para_list.Add(var1);
                    //para_list.Add(var2);
                    para_list.Add(0);
                    para_list.Add(64);
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    this.m_master.WriteSingleRegister(slave, MoonsPositiveRotation, (ushort)para);
                    //this.m_master.WriteMultipleRegisters(slave, MoonsPositiveRotation, para_list.ToArray());
                    Thread.Sleep(10);
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("SetMoonsPosition exception:" + ex.Message);
                    return false;
                }
            }
            
        }

        /// <summary>
        /// 设置反转速度上限
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsReversingRotation(byte slave, int para)
        {
            lock (loc)
            {
                try
                {
                    IList<ushort> para_list = new List<ushort>();
                    ushort var1 = 0;
                    ushort var2 = 0;
                    this.IntToHex(para, out var1, out var2);
                    //para_list.Add(var1);
                    //para_list.Add(var2);
                    para_list.Add(0x0);
                    para_list.Add(0x64);
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    this.m_master.WriteSingleRegister(slave, MoonsReversingRotation, (ushort)para);
                    //this.m_master.WriteMultipleRegisters(slave, MoonsReversingRotation, para_list.ToArray());
                    Thread.Sleep(10);
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("SetMoonsPosition exception:" + ex.Message);
                    return false;
                }
            }
            
        }

        /// <summary>
        /// 读取当前速度
        /// </summary>
        /// <param name="sale"></param>
        /// <param name="para"></param>
        /// <returns></returns>
        public int GetCurrentSpeed(byte sale)
        {
            lock (loc) 
            {
                try
                {
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    var data = this.m_master.ReadHoldingRegisters(sale, MoonsCurrentSpeed, 1);
                    Thread.Sleep(10);
                    Int16 speed = (Int16)data[0];

                    return (int)speed;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("GetCurrentSpeed exception:" + ex.Message);
                    return -1;
                }
            }
            return -1;
        }

        /// <summary>
        /// 读取当前扭矩
        /// </summary>
        /// <param name="sale"></param>
        /// <param name="para"></param>
        /// <returns></returns>
        public int GetmotorSpeed(byte sale)
        {
            lock (loc)
            {
                try
                {
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    var data = this.m_master.ReadHoldingRegisters(sale, MoonsmotorSpeed, 1);
                    Thread.Sleep(10);
                    Int16 speed = (Int16)data[0];

                    return (int)speed;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("GetmotorSpeed exception:" + ex.Message);
                    return -1;
                }
            }
            return -1;
        }

        public void IntToHex(int number, out ushort h, out ushort l)
        {
            //int a = number & 0x0000ffff;
            //int b = (number >> 16) & 0xffff;
            l = (ushort)(number & 0x0000ffff);
            h = (ushort)((number >> 16) & 0xffff);
        }

        /// <summary>
        /// 低位在前
        /// </summary>
        /// <param name="pDataBytes"></param>
        /// <returns></returns>
        public byte[] CRC16LH(byte[] pDataBytes)
        {
            ushort crc = 0xffff;
            ushort polynom = 0xA001;

            for(int i=0;i<pDataBytes.Length;i++)
            {
                crc ^= pDataBytes[i];
                for(int j = 0;j<8;j++)
                {
                    if((crc & 0x01)==0x01)
                    {
                        crc >>= 1;
                        crc ^= polynom;
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
            }

            byte[] result = BitConverter.GetBytes(crc);
            //byte[] result = BitConverter.GetBytes(crc).Reverse().ToArray();   //高字节在前

            return result;
        }

        /// <summary>
        /// 设置电机参数，并立即运行
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsPosition(byte slave, ushort Address, ushort para)
        {
            lock (loc)
            {
                try
                {
                    FileWriter.WriteLog("----0-----");
                    m_serial.DiscardInBuffer();
                    FileWriter.WriteLog("----1-----");
                    m_serial.DiscardOutBuffer();
                    FileWriter.WriteLog("----2-----");
                    this.m_master.WriteSingleRegister(slave, Address, para);
                    FileWriter.WriteLog("SetMoonsPosition completed");
                    Thread.Sleep(10);
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("SetMoonsPosition exception:" + ex.Message);
                    return false;
                }
            }
        }

        /// <summary>
        /// 电机运行
        /// </summary>
        /// <param name="slave">电机从站</param>
        /// <returns></returns>
        public bool RTU_MotorRun(byte slave, int Run_para, ushort H_para = 100, ushort L_para = 20, ushort Speed_para = 150, ushort Acc_para = 100, ushort Dec_para = 100)
        {
            lock (loc)
            {
                try
                {
                    //if (!SetMoonsPosition(1, abs_Address, 1))
                    //{
                    //    return false;
                    //}
                    IList<ushort> para_list = new List<ushort>();
                    ushort var1 = 0;
                    ushort var2 = 0;
                    this.IntToHex(Run_para, out var1, out var2);
                    para_list.Add(var1);
                    para_list.Add(var2);
                    //para_list.Add(0x0);
                    //para_list.Add(0x64);
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();
                    if (!SetMoonsPosition(slave, posH_Address, para_list[0]))
                    {
                        return false;
                    }
                    if (!SetMoonsPosition(slave, posL_Address, para_list[1]))
                    {
                        return false;
                    }
                    if (!SetMoonsPosition(slave, Speed_Address, Speed_para))
                    {
                        return false;
                    }
                    //if (!SetMoonsPosition(1, Acc_adsAddress, Acc_para))
                    //{
                    //    return false;
                    //}
                    //if (!SetMoonsPosition(1, Dec_Address, Dec_para))
                    //{
                    //    return false;
                    //}
                    if (!SetMoonsPosition(slave, Abs_triger_Address, 0x10))
                    {
                        return false;
                    }
                    Thread.Sleep(200);
                    //bool IsInPosition = CheckHomeStatusRTU(1); ;
                    //if (IsInPosition == false)
                    //{
                    //    return false;
                    //}
                    bool value = WaitStopRTU(slave);

                    return value;
                }
                catch ( Exception ex)
                {
                    FileWriter.WriteLog(string.Format("RTU_MotorRun slave={0} :{1}", slave, ex.Message));
                    return false;
                }
               
            }
            
        }
       
        /// <summary>
        /// 电机回原
        /// </summary>
        /// <param name="slave">电机从站</param>
        /// <returns></returns>
        public bool RTU_MotorGoHome(byte slave, ushort H_para = 100, ushort L_para = 20)
        {
            lock (loc)
            {
                try
                {
                    //if (!SetMoonsPosition(1, Home_M_Address, 0x04))
                    //{
                    //    return false;
                    //}
                    //if (!SetMoonsPosition(1, Home_Speed_H_adsAddress, H_para))
                    //{
                    //    return false;
                    //}
                    //if (!SetMoonsPosition(1, Home_Speed_L_Address, L_para))
                    //{
                    //    return false;
                    //}
                    Thread.Sleep(10);
                    if (!SetMoonsPosition(slave, Home_triger_Address, 0x20))
                    {
                        FileWriter.WriteLog(string.Format("RTU_MotorGoHome slave={0} :fail", slave));
                        return false;
                    }
                    Thread.Sleep(200);
                    bool IsInPosition = CheckHomeStatusRTU(slave);
                    if (IsInPosition == false)
                    {
                        return false;
                    }
                    //bool value = WaitStopRTU(1);
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("RTU_MotorGoHome slave={0} :{1}", slave, ex.Message));
                    return false;
                }
                
            }
            
        }

        /// <summary>
        /// 电机回原 不等待是否回原到位
        /// </summary>
        /// <param name="slave"></param>
        /// <param name="H_para"></param>
        /// <param name="L_para"></param>
        /// <returns></returns>
        public bool RTU_MotorGoHome_1(byte slave, ushort H_para = 100, ushort L_para = 20)
        {
            lock (loc)
            {
                try
                {
                    Thread.Sleep(10);
                    if (!SetMoonsPosition(slave, Home_triger_Address, 0x20))
                    {
                        FileWriter.WriteLog(string.Format("RTU_MotorGoHome slave={0} :fail", slave));
                        return false;
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("RTU_MotorGoHome slave={0} :{1}", slave, ex.Message));
                    return false;
                }

            }

        }

        /// <summary>
        /// 检测电机是否在home
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool CheckHomeStatusRTU(byte slave, int timeout = 20)
        {
            DateTime end = DateTime.Now.AddSeconds(timeout);
            Thread.Sleep(1000);
            int status = 0;

            while (DateTime.Now <= end)
            {
                try
                {
                    clear_alarmRTU(slave);
                    var data = m_master.ReadHoldingRegisters(slave, MoonsHomeStatus, 2);
                    //Console.WriteLine(data[0]);
                    char[] value=Convert.ToString(data[0], 2).ToArray();
                    #region MyRegion
                    //if (value.Length >= 3&&value.Length<5)
                    //{
                    //    if (value[0] == '1')
                    //    {
                    //        FileWriter.WriteLog("电机在运行中！");
                    //    }
                        
                    //}
                    //if (value.Length > 3 && value.Length < 7)
                    //{
                    //    if (value[0] == 1)
                    //    {
                    //        FileWriter.WriteLog("电机在运行中！");
                    //    }
                    //}
                    #endregion
                    if (value.Length >= 7)
                    {
                        if (value[6] == '0' && value[2] == '1')
                        {
                            FileWriter.WriteLog("MoonMotor location in home！");
                            return true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("CheckHomeStatusRTU slave={0} :{1}", slave,ex.Message));
                    return false;
                }
                Thread.Sleep(200);
            }
            FileWriter.WriteLog(string.Format("CheckHomeStatusRTU slave={0}Timeout", slave));
            return true;
        }
        /// <summary>
        /// 清除报警
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool clear_alarmRTU(byte slave)
        {
            try
            {
                if (m_serial.IsOpen)
                {
                    m_master.WriteSingleRegister(slave, 0x7C, 0xBA);
                    Thread.Sleep(200);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                FileWriter.WriteLog("clear_alarm exception:" + ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 电机停止
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool Motor_Stop(byte slave)
        {
            lock (loc)
            {
                try
                {
                    m_serial.DiscardInBuffer();
                    m_serial.DiscardOutBuffer();

                    if (!SetMoonsPosition(slave, Abs_triger_Address, 0x40))
                    {
                        return false;
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog("Motor_Stop exception:" + ex.Message);
                    return false;
                }
                
            }
            
        }

        /// <summary>
        /// 获取电机状态
        /// </summary>
        /// <param name="slave"></param>
        /// <returns>-1返回失败，否则返回状态</returns>
        public int GetMoonsStatus(byte slave)
        {
            lock (loc)
            {
                int trycnt = 3;
                while (trycnt >= 1)
                {
                    try
                    {
                        if (m_serial.IsOpen)
                        {
                            m_serial.DiscardInBuffer();
                            m_serial.DiscardOutBuffer();
                            var data = this.m_master.ReadHoldingRegisters(slave, 0x6002, 0x01);
                            Thread.Sleep(10);
                            return data[0];
                        }
                        else
                        {
                            trycnt -= 1;
                            Thread.Sleep(1000);
                        }
                    }
                    catch (Exception ex)
                    {
                        trycnt -= 1;
                        FileWriter.WriteLog("GetMoonsStatus exception:" + ex.Message);
                    }
                }

                return -1;
            }
        }
        /// <summary>
        /// 等待停止
        /// </summary>
        /// <param name="slave"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool WaitStopRTU(byte slave, int timeout = 20)
        {
            lock (loc)
            {
                try
                {
                    DateTime end = DateTime.Now.AddSeconds(timeout);
                    int status = 0;
                    while (DateTime.Now <= end)
                    {
                        status = this.GetMoonsStatus(slave);
                        if (status == 0)
                        {
                            FileWriter.WriteLog(string.Format("slave={0} stop", slave));
                            return true;
                        }
                        else if (status == 16 || status == 32 || status == 64)
                        {
                            FileWriter.WriteLog(string.Format("slave={0} move fail, status={1}：", slave, status));
                            //Thread.Sleep(100);          //等待1秒
                            //Console.WriteLine(status);
                            return false;
                        }
                        //正在运行
                        else if (status == 256)
                        {
                            Thread.Sleep(100);          //等待1秒
                            //Console.WriteLine(status);
                        }
                        Thread.Sleep(200);
                    }
                    FileWriter.WriteLog(string.Format("WaitStopRTU slave={0} Timeout", slave));
                    return false;
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("WaitStopRTU slave={0} Exception:{1}", slave,ex.Message));
                    throw;
                } 
            }
        }

       
    }

    #endregion

    #region 步进电机---TCP通信
    /// <summary>
    /// 步进电机--tcp通信
    /// </summary>
    public class MoonMotorTCP
    {

        private const int MoonsImmediateControlAddress = 0x7C;   //急停地址
        private const int MoonsHomeStatus = 0x3C;                //检测原点地址
        private const int MoonsHomePositonAddress = 0x7C;        //设置立即运动和回原地址
        private const int MoonsStatusAddress = 0x01;             //获取电机状态地址
        private const int MoonsPositionAddress = 0x1B;           //设置电机位置地址

        private string m_ip = "127.0.0.1";
        private int m_port = 502;
        private ModbusIpMaster m_master;
        private TcpClient m_client;


        private object loc = new object();

        public MoonMotorTCP(string ip, int port)
        {
            this.m_ip = ip;
            this.m_port = port;
        }
#if (USE_STANDER_CONNECT)
        private bool IsOnline()
        {
            bool pl = m_client.Client.Poll(1000, SelectMode.SelectRead);
            bool val = (m_client.Client.Available == 0) ? true : false;
            bool connect = m_client.Client.Connected;


            return !((pl && val) || (!connect));
            //return !(
                
            //    (
            //    m_client.Client.Poll(1000, SelectMode.SelectRead) 
            //    && 
            //    (m_client.Client.Available == 0)
            //    ) 

            //    || !m_client.Client.Connected
                
            //    );
        }
#endif
        /// <summary>
        /// 打开端口
        /// </summary>
        /// <returns></returns>
        public bool OpenPort()
        {
            lock (loc)
            {
                try
                {
                    IPAddress address = IPAddress.Parse(m_ip);
#if (!USE_STANDER_CONNECT)
                    m_client = new TcpClient(address.ToString(), 502);
                    Int32 count = 3;
                    while ((m_client == null) && (count >= 0))
                    {
                        m_client = new TcpClient(address.ToString(), 502);
                        count--;
                    }

                    if (m_client == null)
                    {
                        FileWriter.WriteLog("creat m_client fail");
                        return false;
                    }
                    //m_client.SendTimeout = 1;
                    //m_client = new TcpClient();
                    //m_client.Connect(m_ip, 502);
                    m_master = ModbusIpMaster.CreateIp(m_client);
                    count = 3;
                    while ((m_master == null) && (count >= 0))
                    {
                        m_master = ModbusIpMaster.CreateIp(m_client);
                        count--;
                    }
                    if (m_master != null)
                    {
                        //if (this.CheckHomeStatus(1) == false);

                        return true;
                    }
                    else
                    {
                        FileWriter.WriteLog("creat m_master fail");
                        return false;
                    }
#else
                bool res;
                m_client = new TcpClient();
                IAsyncResult asy = null;
                try
                {
                    asy = m_client.BeginConnect(address, 502, null, null);
                    Thread.Sleep(500);
                }
                catch (Exception e)
                {
                    Console.WriteLine("BeginConnect exception is" + e.ToString());
                }
                if(asy.IsCompleted)
                {
                    if (IsOnline())
                    {
                        m_master = ModbusIpMaster.CreateIp(m_client);
                        Console.WriteLine("tcp is already connected");
                        res = true;
                    }
                    else
                    {
                        Console.WriteLine("tcp connect is not Online ###################");
                        FileWriter.WriteLog(string.Format("tcp connect is not Online:{0},{1}", address.ToString(), m_ip.ToString()));
                        res = false;
                    }
                }
                else
                {
                    Console.WriteLine("IAsyncResult IsCompleted  fail ###################");
                    FileWriter.WriteLog(string.Format("IAsyncResult IsCompleted  fail:{0},{1}", address.ToString(), m_ip.ToString()));
                    res = false;
                    m_client.Close();
                }
                return res;
#endif
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("连接异常:{0}  ip:{1} port:{2}", ex.Message,this.m_ip,this.m_port));
                    //    m_client.Close();
                    return false;
                }
            }
            
        }

        /// <summary>
        /// 返回连接状态，是返回true，否重连返回重连状态
        /// </summary>
        /// <returns></returns>
        private bool isconect()
        {
            //   Console.WriteLine(m_client.Connected);
            //   if(m_client.Connected == false)
            if (this.m_client.Connected)
            {
                try
                {
                    // m_client.Close();
                    OpenPort();
                    Thread.Sleep(100);
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("连接异常:{0}  ip:{1} port:{2}", ex.Message, this.m_ip, this.m_port));
                }
            }
            else //没有连接也打开端口连接下（端口丢失重连）
            {
                try
                {
                    OpenPort();
                    Thread.Sleep(100);
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("连接异常:{0}  ip:{1} port:{2}", ex.Message, this.m_ip, this.m_port));
                }
            }
            if (m_client.Connected == false)
            {
                FileWriter.WriteLog("m_client.Connected = false");
            }
            return m_client.Connected;

        }

        /// <summary>
        /// 关闭端口
        /// </summary>
        public void Close()
        {
            lock (loc)
            {
                try
                {
                    if (m_client != null)
                        m_client.Close();
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("关闭端口异常:{0}  ip:{1} port:{2}", ex.Message, this.m_ip, this.m_port));
                }
            }
        }

        /// <summary>
        /// 电机直线运动
        /// </summary>
        /// <param name="slave">从站地址</param>
        /// <param name="pos">运动距离(脉冲值)</param>
        /// <param name="speed">运动速度</param>
        /// <param name="acceleration">加速度</param>
        /// <param name="deceleration">减速度</param>
        /// <param name="ratio">减速比</param>
        /// <param name="lead">导程</param>
        /// <param name="timeout">超时时间，单位秒</param>
        /// <returns></returns>
        public bool MoveLine(byte slave, int pos, ushort speed, ushort acceleration, ushort deceleration, bool sny = true, ushort ratio = 1, ushort lead = 2, int timeout = 20)
        {
            try
            {
                //if(!this.SetMoonsImmediatelyStop(slave))
                //{
                //    FileWriter.WriteLog("motor immediately stop fail");
                //    return false;
                //}

                if (!isconect())
                {
                    return false;
                }

                IList<ushort> para_list = new List<ushort>();
                para_list.Add(acceleration);
                para_list.Add(deceleration);
                para_list.Add(speed);
                ushort var1 = 0;
                ushort var2 = 0;
                this.IntToHex(pos, out var1, out var2);
                para_list.Add(var1);
                para_list.Add(var2);

                if (sny)
                {
                    return this.SetMoonsPosition(slave, para_list.ToArray());
                }
                else
                {
                    this.m_master.WriteMultipleRegisters(slave, MoonsPositionAddress, para_list.ToArray());
                    this.m_master.WriteSingleRegister(slave, MoonsHomePositonAddress, 0x67);
                    //读取当前位置
                    int pos_now = GetMoonsLocalPosition(slave);
                    if (Math.Abs(pos_now-pos) > 100)
                    {
                        FileWriter.WriteLog(string.Format("MoveLine slave={0} pos_now :{1} pos_target:{2}", slave, pos_now.ToString(),pos));
                        return false;
                    }
                    return true;
                }

            }
            catch (Exception ex)
            {
                FileWriter.WriteLog(string.Format("MoveLine slave={0} Exception :{1}", slave, ex.Message));
                return false;
            }
        }


        /// <summary>
        /// 等待到位信号，到位正常返回true
        /// </summary>
        /// <param name="slave"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool WaitStopTCP(byte slave, double timeout = 20)
        {
            try
            {
                DateTime end = DateTime.Now.AddSeconds(timeout);
                Thread.Sleep(1);
                int status = 0;
                while (DateTime.Now <= end)
                {
                    status = this.GetMoonsStatus(slave);

                    if (status == 9)
                    {

                        FileWriter.WriteLog(string.Format("slave={0} stop", slave));
                        Console.WriteLine(status);
                        return true;
                    }
                    else if (status == 521)
                    {
                        FileWriter.WriteLog(string.Format("slave={0} move fail：521", slave));
                        return false;
                    }
                    Thread.Sleep(50);
                }
                FileWriter.WriteLog(string.Format("WaitStopTCP slave={0} Timeout", slave));
                return false;
            }
            catch (Exception ex)
            {
                FileWriter.WriteLog(string.Format("WaitStopTCP slave={0} Exception :{1}", slave,ex.Message));
                return false;

            }
            
        }

        /// <summary>
        /// 检测电机是否在home
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool CheckHomeStatus(byte slave, int timeout = 20)
        {
            DateTime end = DateTime.Now.AddSeconds(timeout);
            Thread.Sleep(200);
            int status = 0;
            clear_alarmTCP(slave);
            while (DateTime.Now <= end)
            {
                try
                {
                    var data = m_master.ReadHoldingRegisters(slave, MoonsHomeStatus, 2);
                    if ((data[0] == 1 || data[1] == 1))
                        return true;
                    else
                        Thread.Sleep(200);
                }
                catch (Exception ex)
                {
                    FileWriter.WriteLog(string.Format("CheckHomeStatus slave={0} Exception:{1}", slave, ex.Message));
                    return false;
                }
            }
            FileWriter.WriteLog(string.Format("CheckHomeStatus slave={0} Check RunHome Timeout！", slave));
            return false;
        }

        /// <summary>
        /// 清除报警信息
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool clear_alarmTCP(byte slave)
        {
            try
            {
                if (isconect())
                {
                    m_master.WriteSingleRegister(slave, 0x7C, 0xBA);
                    Thread.Sleep(2000);
                    return true;
                }
                else
                {
                    FileWriter.WriteLog(string.Format("clear_alarmTCP slave={0} 连接失败", slave));
                    return false;
                }
            }
            catch (Exception ex)
            {
                FileWriter.WriteLog(string.Format("clear_alarmTCP slave={0} Exception:{1}", slave, ex.Message));
                return false;
            }
        }
        

        /// <summary>
        /// hone复位
        /// </summary>
        /// <param name="slave"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetMoonsHome(byte slave, int timeout = 120)
        {
            lock (loc)
            {
                Thread.Sleep(200);
                UInt16 try_count = 3;
                bool res = false;
                while (try_count >= 0)
                {
                    try
                    {
                        //if (!this.SetMoonsImmediatelyStop(slave))
                        //{
                        //    FileWriter.WriteLog("SetMoonsImmediatelyStop before SetMoonsHome fail");
                        //    return false;
                        //}
                        //                if(this.)
                        IList<ushort> para_list = new List<ushort>();
                        para_list.Add(0x78);
                        para_list.Add(0x01);
                        if (this.isconect())
                        {
                            this.m_master.WriteMultipleRegisters(slave, MoonsHomePositonAddress, para_list.ToArray());
                            //bool value = WaitStopTCP(slave);
                            //return value;
                            bool IsInPosition = this.CheckHomeStatus(slave);
                            if (IsInPosition == false)
                            {
                                FileWriter.WriteLog(string.Format("slave={0} 检测在Home失败！", slave));
                                //return false;
                            }
                            else { return true; }

                            //DateTime end = DateTime.Now.AddSeconds(timeout);

                            //while (DateTime.Now <= end)
                            //{
                            //    Thread.Sleep(100);
                            //    IsInPosition = this.CheckHomeStatus(slave);
                            //    if (IsInPosition)
                            //    {
                            //        bool value = WaitStopTCP(slave);
                            //        return value;
                            //    }
                            //}
                        }
                        else
                        {
                            try_count -= 1;
                            Thread.Sleep(1000);
                        }
                    }
                    catch (Exception ex)
                    {
                        try_count -= 1;
                        FileWriter.WriteLog(string.Format("SetMoonsHome slave={0} Exception:{1}", slave, ex.Message));
                        return false;
                    }
                }
                return res;
            }
            
        }

        /// <summary>
        /// 设置电机位置参数，并立即运动
        /// </summary>
        /// <param name="slave"></param>
        /// <param name="para_list"></param>
        /// <returns></returns>
        public bool SetMoonsPosition(byte slave, ushort[] para_list)
        {
            int trycnt = 3;
            while (trycnt >= 1)
            {
                try
                {
#if (!USE_STANDER_CONNECT)
                    if (this.isconect())
#else
                    if(true)
#endif
                    {
                      
                        this.m_master.WriteMultipleRegisters(slave, MoonsPositionAddress, para_list);
                        if (this.SetMoonsImmediatelyMove(slave)==false)
                        {
                            return false;
                        }

                        bool value = WaitStopTCP(slave);
                        return value;
                    }
                    else
                    {
                        trycnt -= 1;
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    trycnt -= 1;
                    FileWriter.WriteLog(string.Format("SetMoonsPosition slave={0} Exception:{1}", slave, ex.Message));
                }
            }
            FileWriter.WriteLog(string.Format("SetMoonsPosition slave={0} fail", slave));
            return false;
        }

        /// <summary>
        /// 立即运动
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsImmediatelyMove(byte slave)
        {
            int trycnt = 3;
            while (trycnt >= 1)
            {
                try
                {
#if (!USE_STANDER_CONNECT)
                    if (this.isconect())
#else
                    if(true)
#endif
                    {
                        this.m_master.WriteSingleRegister(slave, MoonsHomePositonAddress, 0x67);
                        return true;
                    }
                    else
                    {
                        trycnt -= 1;
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    trycnt -= 1;
                    FileWriter.WriteLog(string.Format("SetMoonsImmediatelyMove slave={0} Exception:{1}", slave, ex.Message));
                }
            }
            FileWriter.WriteLog(string.Format("SetMoonsImmediatelyMove slave={0} fail", slave));
            return false;
        }

        /// <summary>
        /// 立即停止
        /// </summary>
        /// <param name="slave"></param>
        /// <returns></returns>
        public bool SetMoonsImmediatelyStop(byte slave)
        {
            int trycnt = 3;
            while (trycnt >= 1)
            {
                try
                {
                    if (this.isconect())
                    {
                        this.m_master.WriteSingleRegister(slave, MoonsImmediateControlAddress, 0xE1);
                        return true;
                    }
                    else
                    {
                        trycnt -= 1;
                        Thread.Sleep(1);
                    }
                }
                catch (Exception ex)
                {
                    trycnt -= 1;
                    FileWriter.WriteLog(string.Format("SetMoonsImmediatelyStop slave={0} Exception:{1}", slave, ex.Message));
                }
            }
            FileWriter.WriteLog(string.Format("SetMoonsImmediatelyStop slave={0} fail", slave));
            return false;
        }

        /// <summary>
        /// 获取电机状态
        /// </summary>
        /// <param name="slave"></param>
        /// <returns>-1返回失败，否则返回状态</returns>
        public int GetMoonsStatus(byte slave)
        {
            int trycnt = 3;
            while (trycnt >= 1)
            {
                try
                {
                    if (this.isconect())
                    {
                        var data = this.m_master.ReadHoldingRegisters(slave, MoonsStatusAddress, 1);
                        return data[0];
                    }
                    else
                    {
                        trycnt -= 1;
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    trycnt -= 1;
                    FileWriter.WriteLog(string.Format("GetMoonsStatus slave={0} Exception:{1}", slave, ex.Message));
                }
            }
            FileWriter.WriteLog(string.Format("GetMoonsStatus slave={0} fail", slave));
            return -1;

        }

        public int GetMoonsLocalPosition(byte slave)
        {
            int trycnt = 3;
            while (trycnt >= 1)
            {
                try
                {
                    if (this.isconect())
                    {
                        var data = this.m_master.ReadHoldingRegisters(slave, MoonsPositionAddress, 5);
                        int pos =To_Int(data[3], data[4]);
                        return pos;
                    }
                    else
                    {
                        trycnt -= 1;
                        Thread.Sleep(1000);
                    }
                }
                catch (Exception ex)
                {
                    trycnt -= 1;
                    FileWriter.WriteLog(string.Format("GetMoonsStatus slave={0} Exception:{1}", slave, ex.Message));
                }
            }
            FileWriter.WriteLog(string.Format("GetMoonsStatus slave={0} fail", slave));
            return -1;
        }


        public void IntToHex(int number, out ushort h, out ushort l)
        {
            //int a = number & 0x0000ffff;
            //int b = (number >> 16) & 0xffff;
            l = (ushort)(number & 0x0000ffff);
            h = (ushort)((number >> 16) & 0xffff);
        }

        /// <summary>
        /// 读取当前点位
        /// </summary>
        /// <param name="h"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        public int To_Int(ushort h, ushort l)
        {
            return (h << 16) | l;
        }
    }

    #endregion
}
