using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using CommonClassLib;
using ICommLayer;
using DBFactory;
namespace SimensCP5611
{
    /// <summary>
    /// 通过西门子的CP5611卡实现Profibus总线方式的通讯接口派生类
    /// 获得设备状态类
    /// 创建者：Richard.Liu
    /// </summary>
    public class CGetDeviceState:IGetDeviceState
    {
        DBOperator dbo = new DBOperator();
        string _commLayerError;

        public string CommLayerError
        {
            get { return _commLayerError; }
            set { _commLayerError = value; }
        }
        public CGetDeviceState()
        {
            dbo.Open();
            
        }
        
        //~CGetDeviceState()
        //{
        //    dbo.Close();
        //}

        /// <summary>
        ///检测开关：  0-无货
        ///        1-有货
        ///第1字	
        ///可下达指令的设备：读/写标志位
        ///1-写入数据  
        ///2-读出数据正确  
        ///确认按钮： 
        ///1-无货确认  
        ///2-有货确认  
        ///	第2字  		
        ///可下达指令的设备：命令
        ///堆垛机：
        ///1-任务完成
        ///其他植表示错误
         ///           穿梭车：	
        ///1-接货完成
        ///2-送货完成
        ///3-停止完成
        ///4-到1#位置
        ///5-到2#位置
        ///    …
        ///其他植表示错误
        ///            输送机、台车：	
        ///1-入库完成	
        ///2-出库完成	
        ///3-送货完成	
        ///4-停止完成	
        ///其他植表示错误
        ///确认按钮： 
        ///一个变化的值，每确认一次，该值变化一次，以标志一个
        ///新的确认消息。例如可以是0、1交替变化，也可以是递
        ///增变化。
        ///第3字	   任务号，即上位机下达任务时的任务号
        ///第4字	   堆垛机：
        ///终点X坐标（沿轨道方向）
        ///              穿梭车、台车、输送机：
        ///前三个字的异或值
        ///   （第5字以后部分只对堆垛机有意义）
        ///第5字	   终点Y坐标（沿高度方向）
        ///第6字   前5个字的异或值
        /// </summary>
        /// <param name="DeviceIndex">设备编号</param>
        /// <returns>获得上行消息成功后，发送应答消息后返回6或4个字节型状态</returns>
        public int [] GetDeviceState(int DeviceIndex, int TaskIndex)
        {
            try
            {
                int[] _Rword = new int[6];
                byte[] _RRword = new byte[200];
                DataSet ds = dbo.ExceSQL("SELECT  F_DeviceIndex,F_DeviceKindIndex, F_DBWAddress,  F_DBWSendLength, F_DBWGetLength FROM T_Base_Device where F_DeviceIndex=" + DeviceIndex);
                DataView dv = ds.Tables[0].DefaultView;
                if (ds.Tables[0].DefaultView.Count > 0)
                {
                    if (Convert.ToDecimal(dv[0]["F_DBWGetLength"]) > 1)
                    {

                        _RRword = CSimensCP5611.DB_Read_CP5611(1, 2, Convert.ToInt16(dv[0]["F_DBWAddress"]), Convert.ToInt16(dv[0]["F_DBWGetLength"])*2);
                    }
                    else//光电开关一类的位状态bit1--bit16
                    {
                        int add = 0;
                        int Bit = Convert.ToInt16(Convert.ToDecimal(dv[0]["F_DBWGetLength"]) * 16) - 1;//转换成bit0--bit15
                        if (Bit > 7)
                        {
                            add = 1;
                            Bit = Bit - 8;
                        }
                        else
                        {
                            add = 0;
                            
                        }
                        _RRword = CSimensCP5611.DB_Read_CP5611(1, 2, Convert.ToInt16(dv[0]["F_DBWAddress"])+add, 1, Bit);
                        _Rword[0] = _RRword[0];
                        _Rword[1] = 3;//3-检测开关状态
                        _Rword[2] = TaskIndex;//任务号
                        _Rword[3] = 0;
                        _Rword[4] = 0;
                        _Rword[5] = DeviceIndex;//设备号索引
                        return _Rword;

                    }

                    if (_RRword == null)
                    {
                        _commLayerError = "SimensCP5611.CGetDeviceState" + ":GetDeviceState---" + CSimensCP5611.ErrorsText;
                        return null;
                    }

                }
                else
                {
                    return null;
                }

                for (int g = 0; g <= 5; g++)
                {
                    _Rword[g] = _RRword[(2 * g)] * 256 + _RRword[(2 * g + 1)];
                }

                //ds.Dispose();
                int _RXor = 0;
                if (_Rword != null)
                {
                    if (Convert.ToInt16(dv[0]["F_DeviceKindIndex"]) == 1)//堆垛机类型设备
                    {
                        _RXor = _Rword[0];
                        for (int i = 1; i <= 4; i++)
                        {
                            _RXor = _RXor ^ _Rword[i];
                        }
                        //_Rword[0] == 1 && PLC读出数据正确
                        if (_Rword[2] == TaskIndex && _RXor == _Rword[5])//(正确反馈TaskIndex的消息应答)
                        {
                            _Rword[5] = DeviceIndex;//设备号索引
                            if (_Rword[1] == 0)
                            {
                                _Rword[1] = 2;//模拟自由口报告坐标
                            }
                            return _Rword;
                        }
                        else
                            return null;
                    }
                    else if (Convert.ToInt16(dv[0]["F_DeviceKindIndex"]) == 28)//光电开关采集器
                    {
                        int[] rr = new int[_RRword.GetUpperBound(0) + 1];
                        for (int i = _RRword.GetLowerBound(0); i <= _RRword.GetUpperBound(0); i++)
                        {
                            rr[i] = Convert.ToInt32(_RRword[i]);
                        }
                        return rr;
                    }
                    else//其它设备类型
                    {
                        _RXor = _Rword[0];
                        for (int i = 1; i <= 2; i++)
                        {
                            _RXor = _RXor ^ _Rword[i];
                        }
                        //_Rword[0] == 1 && PLC读出数据正确
                        if (_Rword[2] == TaskIndex && _RXor == _Rword[3])//(正确反馈TaskIndex的消息应答)
                        {

                            _Rword[3] = 0;
                            _Rword[4] = 0;
                            _Rword[5] = DeviceIndex;//设备号索引
                            return _Rword;
                        }
                        else
                            return null;
                    }
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                _commLayerError = "SimensCP5611.CGetDeviceState" + ":GetDeviceState---" +ex.Message ;
                return null;
            }
        }
    }
}
