using RGD.Common;
using RGD.DataService;
using System;
using System.Collections.Generic;

namespace RGD.OPCClient
{
    public class CGetDeviceState : IGetDeviceState
    {
        private string _commLayerError;

        public string CommLayerError
        {
            get { return _commLayerError; }
            set { _commLayerError = value; }
        }

        public CGetDeviceState()
        {
        }

        /// <summary>
        ///1、下位机给上位机发送设备（任务）状态信息
        ///检测开关：  0-无货1-有货
        ///确认按钮：
        ///第1字节：
        ///一个变化的值，每确认一次，该值变化一次，以标志一个
        ///新的确认消息。例如可以是0、1交替变化，也可以是递
        ///增变化。
        ///第2字节：
        ///1-无货确认
        ///2-有货确认
        ///其他设备：
        ///第1字	节：设备状态
        ///堆垛机：0-空闲
        ///1-正在运行
        ///2-任务完成
        ///3-要求调度重发命令
        ///4-通知调度取消当前任务
        ///其它值表示错误
        /// 穿梭车：
        /// 0-空闲
        /// 1-正在运行
        /// 2-完成
        /// 3-要求调度重发命令
        /// 4-通知调度取消当前任务
        /// 其它值表示错误
        /// 输送机：
        /// 0-空闲
        /// 1-正在运行
        /// 2-完成（只有PC下发的目标设备才允许汇报完成）
        /// 组合机构需要单独定义状态
        /// 其它值表示错误
        /// 第2、3字节： 任务号，即上位机下达任务时的任务号
        /// 第4、5、6、7字节
        /// 堆垛机、穿梭车：
        /// 终点X坐标（沿轨道方向）
        /// （第8字节以后部分只对堆垛机有意义）
        /// 第8、9、10、11字节
        ///  终点Y坐标（沿高度方向）
        ///
        /// 2.下位机给上位机发送条码信息
        /// 托盘条码：
        /// 第1-10字节：由左到右依次存放托盘上的10位条形码信息
        /// 烟箱一号工程码：
        /// 第1-9字节： 由左到右依次存放烟箱上的后9位一号工程码信息
        /// 一号工程码是32位，相同品牌烟箱的一号工程码的前23位相同，
        /// 所以只存放后9位条码。每个码垛位进烟口有两个烟箱一号工程码存放区，
        /// 共18个字节，上位机一次将两个烟箱一号工程码的信息同时读取。
        /// 上位机成功读取18个字节后，把这18个字节全部写入零，
        /// 下位机只有检测到18个字节全都是零时才可以写入新的一号工程码信息。
        ///
        /// 3.下位机给上位机发送现场控制触摸屏申请信号
        /// 第1字节	   申请指令
        /// 1-	重发当前设备指令
        /// 2-	申请修改当前设备所执行任务的目标位置
        /// 第2、3字节	设备索引（当前申请设备的索引）
        /// 第4、5字节	任务号（需要修改目标位置的任务号）
        /// 第6、15字节	托盘条码（当前申请设备上的托盘的条码）
        /// 下位机可能因开关误动作等情况而引起任务记忆丢失，
        /// 此时根据设备上停放托盘的条码可以重新申请获得任务。
        /// 上位机收到此申请后重新发送当前设备的指令。
        /// 有设备发生故障时，下位机可以申请修改任务的目标位置。
        /// 上位机收到此申请后，如果可以找到新的路径，则修改此任务号的目标位置。
        /// 当申请指令为1时，任务号可以是任意值；当申请指令为2时，托盘条码可以是任意值。
        /// </summary>
        /// <param name="DeviceIndex">设备编号</param>
        /// <returns>获得上行消息成功后，发送应答消息后返回22个字的状态</returns>
        public int[] GetDeviceState(int DeviceIndex)//有用
        {
            string[] itemnames;
            int[] _Rword = new int[20];
            List<string> itemvalue = new List<string>();
            Model.MDevice devinfo = BaseDeviceService.GetDeviceInfo(DeviceIndex);
            try
            {
                if (devinfo.DeviceIndex == 0)
                {
                    _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState发生错误：在设备表中没找到设备所引！";
                    return null;
                }
                else
                {
                    CCommonOPCClient.Hostname = AppSettings.GetValue("HostName");//20090922 devinfo.RemoteIP;
                    CCommonOPCClient.ProgID = AppSettings.GetValue("OPCProgID");
                    switch (devinfo.DeviceKind.ToString())
                    {
                        #region 光电开关总的采集

                        case "28":
                            int[] _RRword = new int[(int)devinfo.Dbw2Getlength];
                            byte[] br = CCommonOPCClient.SyncReadAllItems();
                            if (br == null)
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            Array.Copy(br, _RRword, (int)devinfo.Dbw2Getlength);
                            return _RRword;

                        #endregion 光电开关总的采集

                        #region 其他设备

                        case "1"://堆垛机
                            itemnames = new string[5];
                            itemnames[0] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0));
                            itemnames[1] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 1));
                            itemnames[2] = "DB2,int" + Convert.ToString((devinfo.Dbw2Address + 2));
                            itemnames[3] = "DB2,DWORD" + Convert.ToString((devinfo.Dbw2Address + 4));
                            itemnames[4] = "DB2,DWORD" + Convert.ToString((devinfo.Dbw2Address + 8));
                            itemvalue = CCommonOPCClient.SyncReadAllItems(itemnames);
                            if (itemvalue.Count == 0)
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            _Rword[0] = Convert.ToInt32(itemvalue[0]);//读写标志
                            _Rword[1] = Convert.ToInt32(itemvalue[1]);//状态
                            _Rword[2] = Convert.ToInt32(itemvalue[2]);//任务号
                            _Rword[3] = Convert.ToInt32(itemvalue[3]);//X坐标
                            _Rword[4] = Convert.ToInt32(itemvalue[4]);//Y坐标
                            _Rword[5] = DeviceIndex;//设备号索引
                            break;

                        case "2"://输送机
                            itemnames = new string[3];
                            itemnames[0] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0));
                            itemnames[1] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 1));
                            itemnames[2] = "DB2,int" + Convert.ToString((devinfo.Dbw2Address + 2));

                            itemvalue = CCommonOPCClient.SyncReadAllItems(itemnames);
                            if ((itemvalue == null) || (itemvalue.Count == 0))
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            _Rword[0] = Convert.ToInt32(itemvalue[0]);//读写标志
                            _Rword[1] = Convert.ToInt32(itemvalue[1]);//状态
                            _Rword[2] = Convert.ToInt32(itemvalue[2]);//任务号
                            _Rword[3] = 0;
                            _Rword[4] = 0;
                            _Rword[5] = DeviceIndex;//设备号索引
                            break;

                        #region RGV、机器人

                        case "4"://RGV
                            itemnames = new string[4];
                            itemnames[0] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0));
                            itemnames[1] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 1));
                            itemnames[2] = "DB2,int" + Convert.ToString((devinfo.Dbw2Address + 2));
                            itemnames[3] = "DB2,DWORD" + Convert.ToString((devinfo.Dbw2Address + 4));

                            itemvalue = CCommonOPCClient.SyncReadAllItems(itemnames);
                            if ((itemvalue == null) || (itemvalue.Count == 0))
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            _Rword[0] = Convert.ToInt32(itemvalue[0]);//读写标志
                            _Rword[1] = Convert.ToInt32(itemvalue[1]);//状态
                            _Rword[2] = Convert.ToInt32(itemvalue[2]);//任务号
                            _Rword[3] = Convert.ToInt32(itemvalue[3]);//X坐标
                            _Rword[4] = 0;
                            _Rword[5] = DeviceIndex;//设备号索引
                            break;

                        case "13"://机器人申请残盘数量
                            itemnames = new string[4];
                            itemnames[0] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0));
                            itemnames[1] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 1));
                            itemnames[2] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 2));
                            itemnames[3] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 3));

                            itemvalue = CCommonOPCClient.SyncReadAllItems(itemnames);
                            if ((itemvalue == null) || (itemvalue.Count == 0))
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            if (itemvalue[0] != "1") return null;
                            _Rword[0] = Convert.ToInt32(itemvalue[1]);//１＃码垛位
                            _Rword[1] = Convert.ToInt32(itemvalue[2]);//２＃码垛位
                            _Rword[2] = Convert.ToInt32(itemvalue[3]);//３＃码垛位
                            _Rword[3] = 0;
                            _Rword[4] = 0;
                            _Rword[5] = DeviceIndex;//设备号索引
                            break;

                        #endregion RGV、机器人

                        #endregion 其他设备

                        default:
                            break;
                    }
                }
                return _Rword;
            }
            catch (Exception ex)
            {
                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState发生错误：" + ex.Message;
                return null;
            }
            finally
            {
                itemnames = null;
                _Rword = null;
                itemvalue = null;
                devinfo = null;
            }
        }

        public string GetStringData(int DeviceIndex, int TaskIndex)
        {//20091107
            string headstr = "";
            string[] itemnames;
            string retdata = "";
            string[] witemnames;
            byte[] itemvalue;
            object[] obj;
            Model.MDevice devinfo = BaseDeviceService.GetDeviceInfo(DeviceIndex);
            try
            {
                if (devinfo.DeviceIndex == 0)
                {
                    _commLayerError = "OPCClient.CGetDeviceState.GetStringData发生错误：在设备表中没找到设备所引！";

                    return null;
                }
                else
                {
                    CCommonOPCClient.Hostname = AppSettings.GetValue("HostName");//20090922 devinfo.RemoteIP;
                    CCommonOPCClient.ProgID = AppSettings.GetValue("OPCProgID");

                    witemnames = new string[1] { "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0)) };
                    switch (devinfo.DeviceKind.ToString())
                    {
                        #region 托盘条码信息(10个字节)

                        case "7":
                            itemnames = new string[11];
                            itemnames[0] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0));
                            for (int i = 1; i < 11; i++)
                            {
                                itemnames[i] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + i));
                            }
                            obj = CCommonOPCClient.SyncReadItemValues(itemnames);
                            if ((obj == null))
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            if (obj[0].ToString() != "1") return null;
                            itemvalue = new byte[obj.Length];
                            Array.Copy(obj, itemvalue, obj.Length);

                            headstr = itemvalue[0].ToString();
                            for (int i = 1; i <= 10; i++)
                            {
                                retdata += Convert.ToChar(itemvalue[i]);
                            }

                            break;

                        #endregion 托盘条码信息(10个字节)

                        #region 烟箱一号工程码（两组共32个字节+一个标志头）

                        case "21":
                            itemnames = new string[33];
                            itemnames[0] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + 0));
                            for (int i = 1; i < 33; i++)
                            {
                                itemnames[i] = "DB2,byte" + Convert.ToString((devinfo.Dbw2Address + i));
                            }
                            obj = CCommonOPCClient.SyncReadItemValues(itemnames);
                            if ((obj == null))
                            {
                                _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                                return null;
                            }
                            if (obj[0].ToString() != "1") return null;
                            itemvalue = new byte[obj.Length];
                            Array.Copy(obj, itemvalue, obj.Length);

                            headstr = itemvalue[0].ToString();
                            for (int i = 1; i <= 32; i++)
                            {
                                retdata += Convert.ToChar(itemvalue[i]);
                            }
                            break;

                        #endregion 烟箱一号工程码（两组共32个字节+一个标志头）

                        default:
                            break;
                    }
                }
                if (headstr == "1")
                {
                    string[] wv = new string[1] { "2" };
                    if (CCommonOPCClient.SyncWriteAllItemValue(witemnames, wv) == false)
                    {
                        _commLayerError = "OPCClient.CGetDeviceState.GetDeviceState：" + CCommonOPCClient.OpcError;
                        return null;
                    }
                    else
                    {
                        return retdata;
                    }
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                _commLayerError = "OPCClient.CGetDeviceState.GetStringData发生错误：" + ex.Message;
                return null;
            }
            finally
            {
                headstr = null;
                itemnames = null;
                retdata = null;
                witemnames = null;
                itemvalue = null;
                obj = null;
                devinfo = null;
            }
        }
    }
}