using bizFacade;
using DataLinkMesWork;
using DataLinkMesWork2;
//using DataMirrorToolsPage;
using MesDataFunction;
using MesServerFunctions;
using MesServerWork;
using MesWork;
using MesWork.PLC;
using MesWorkMqtt;
using MisDataFun;
using MQTTnet;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Protocol;
using NPOI.SS.UserModel;
using NPOI.XWPF.UserModel;
using OpcData;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using SystemFramework;
using static NPOI.HSSF.Util.HSSFColor;
using static System.Net.Mime.MediaTypeNames;

namespace MisDataSaveDate
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj1"></param>
    /// <param name="obj2"></param>
    public delegate void RefreshForm(object obj1, EventArgs obj2);
    public partial class MisDataFun: Form
    {
        static Hashtable hashtableTopicList = new Hashtable();
        static bool OnLineMqtt = false;
        private WebApi.InitServer initServer = null;
        /// <summary>
        /// 
        /// </summary>
        public static int IsWriteMonitorLog = Convert.ToInt32(ConfigurationManager.AppSettings["IsWriteMonitorLog"]);
        /// <summary>
        /// 
        /// </summary>
        public static int IsDemoMesServer = Convert.ToInt32(ConfigurationManager.AppSettings["IsDemoMesServer"]);
        public static string IsRecordTagStatus = ConfigurationManager.AppSettings["IsRecordTagStatus"];
        static bool loadFinish = false;
        /// <summary>
        /// 允许使用附加功能的变量，只有在系统开始加载Tag时，才允许读取PLC数据
        /// </summary>
        public static bool AllowLoad;
        /// <summary>
        /// 
        /// </summary>
        List<String> opNameList;
        /// <summary>
        /// 
        /// </summary>
        DateTime StartTime;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj1"></param>
        /// <param name="obj2"></param>
        public delegate void RefreshForm(object obj1, EventArgs obj2);
        /// <summary>
        /// 
        /// </summary>
        public static RefreshForm MainFormRefresh, TestPlcStatusDel;
        public BasicData.QualityDataType[] ThisWorkStationData { get; set; }

        public MisDataFun()
        {
            InitializeComponent();
            Never_Know.Hello_You_All_Never_Know = Hello_You_All_Never_Know;
            MisData01();
            Init_dataGridView_CheckOpName();
            MIS_BASE.InitHashtable_MesServerCode();
            InitMesSerVerCode();
            // 从配置读取 端口
            initServer = new WebApi.InitServer(Convert.ToInt32(ConfigurationManager.AppSettings["ApiPort"]));
            ApplicationConfig.ConnectionString_MES = ConfigurationManager.AppSettings["ConnectionString_MES"];

            // 查所有点位 挨个去查数值 查看是否有数值 = -1 or -2
            //var sql =
            //    $" SELECT" +
            //    $"  *" +
            //    $" FROM [MES_基本变量_原始数据]" +
            //    $" WHERE 工位号 = 'OP070' and 是否启用 = 1";
            //DataAccess2.ExecuteDataTable(sql, out DataTable dt);
            //if (dt.Rows.Count > 0)
            //{
            //    for (int i = 0; i <  dt.Rows.Count; i++)
            //    {
            //        DataRow row = dt.Rows[i];
            //        int code = Convert.ToInt32(row["变量类型代码"]);
            //        string OpName = row["工位号"].ToString();
            //        if (code== 105 || code == 103) continue;
            //        var data = MIS_BASE.ReadPLC(code, OpName);
            //    }
            //}
            //return;

            // 自监控心跳
            InitAllOpHeartBeat();
        }

        private void InitAllOpHeartBeat()
        {

            DataTable dt;
            DataTable dt1;
            try
            {
                dt1 = BaseDataSystemMES.GetCheckOpName();

                new Thread(new ThreadStart(delegate () {
                    while (true)
                    {
                        for (int i = 0; i < dt1.Rows.Count; i++)
                        {
                            string PLC_HeartBeat;
                            string OpName = dt1.Rows[i]["工位号"].ToString();
                            MIS_BASE.Read_TagTypeID(14, OpName, out PLC_HeartBeat);
                            MIS_BASE.WritePLC(15, OpName, PLC_HeartBeat);
                        }
                        Thread.Sleep(3000);
                    }
                }))
                { IsBackground = true }.Start();

            }
            catch (Exception ex)
            {
            }
        }

        public static DataTable GetCheckOpName()
        {
            DataTable dt = new DataTable();
            string produceName = "MES_计划BOM_工位与名称_查询";
            SqlParameter[] thisParms = null;


            DataAccess2.ExecuteStoredProcedure(produceName, ref thisParms, out dt);

            return dt;
        }

        public void MisData01()
        {
            DataTable dt_Signal;
            DataTable dt_Device;
            DataTable dt_TagTypeDataType;
            dt_Signal = bizFacade.BaseDataSystemMES.dt_Signal();
            dt_Device = bizFacade.BaseDataSystemMES.dt_Device();
            dt_TagTypeDataType = bizFacade.BaseDataSystemMES.dt_TagTypeDataType();
            var mp = new MesWorkPlc();

            StartTime = Convert.ToDateTime(toolStripStatusLabel_StartTime.Text = DateTime.Now.ToString());
            Runtime_Thread();

            if (mp.LoadOPCData(dt_Signal, dt_Device, IsDemoMesServer, IsWriteMonitorLog, true))
            {
                MesDataFunction.LoadTagTypeCodeID.Load(dt_TagTypeDataType);

                //查询出“全部原始基本数据列表”
                var drs = MesWork.PlcLinkForm.dt_BasicData.Select($"是否启用 = 1 and 变量类型代码=101 or 变量类型代码 = 102  or 变量类型代码 = 105 and 监控属性代码 = '{DataLinkMesWork.ApplicationConfig.MES_Code.ToString()}'");
                if (drs.Length > 1)
                {
                    MIS_BASE.BasicDataTagValue = MesWork.PlcLinkForm.dt_BasicData.Select($"是否启用 = 1 and 变量类型代码=101 or 变量类型代码 = 102  or 变量类型代码 = 105 and 监控属性代码 = '{DataLinkMesWork.ApplicationConfig.MES_Code.ToString()}'").CopyToDataTable<DataRow>();
                    if (MIS_BASE.BasicDataTagValue.Columns.Contains("上限值"))
                    {
                        MIS_BASE.BasicDataTagValue.Columns["上限值"].ColumnName = "值上限";
                    }
                    if (MIS_BASE.BasicDataTagValue.Columns.Contains("下限值"))
                    {
                        MIS_BASE.BasicDataTagValue.Columns["下限值"].ColumnName = "值下限";
                    }
                }

                // BasicDataTagValue = MesWork.PlcLinkForm.dt_BasicData.Select($"是否启用 = 1 and 监控属性代码 = '{DataLinkMesWork.ApplicationConfig.MES_Code.ToString()}'").CopyToDataTable<DataRow>();
                //查询出“MES_基本数据_测量范围”
                MesServerWork.MIS_BASE.BasicDataTagValueUpDown = MesWork.PlcLinkForm.dt_BasicData;
                if (MesServerWork.MIS_BASE.BasicDataTagValueUpDown.Columns.Contains("上限值"))
                {
                    MesServerWork.MIS_BASE.BasicDataTagValueUpDown.Columns["上限值"].ColumnName = "值上限";
                }
                if (MesServerWork.MIS_BASE.BasicDataTagValueUpDown.Columns.Contains("下限值"))
                {
                    MesServerWork.MIS_BASE.BasicDataTagValueUpDown.Columns["下限值"].ColumnName = "值下限";
                }
                // 模拟时，写入质量数据
                InitBasicDataTagValue();
                // 变量代码与其他字段的对应关系
                MesServerWork.MIS_BASE.InitHashtableTagID();
                InitcomboBox_OpName();
      
                loadFinish = true;
                AllowLoad = true;
                MainFormRefresh = new RefreshForm(button_ReadData_Click);
                WorkStationNum_Now = comboBox_OpName.SelectedValue.ToString();
                TestPlcStatusDel = new RefreshForm(RefreshPlcConnectStatus);
                if (IsDemoMesServer == 1)
                {
                    toolStripStatusLabel_RunningStatus.Text = "变量模拟";
                    toolStripStatusLabel_RunningStatus.BackColor = System.Drawing.Color.Yellow;
                }
                else
                {
                    toolStripStatusLabel_RunningStatus.Text = "PLC";
                    toolStripStatusLabel_RunningStatus.BackColor = System.Drawing.Color.Green;
                }
                MesWorkPlc.D_OPCTagData_TagDataOnChangeMIS-= OPCTagData_TagDataOnChange;
                MesWorkPlc.D_OPCTagData_TagDataOnChangeMIS+= OPCTagData_TagDataOnChange;
          
            }


        }

        /// <summary>
        /// 获得Function调用信息
        /// </summary>
        private void InitMesSerVerCode()
        {
            MisDataFunDll.MisDataFun.GetMesServerCodeAndMesDll(out MisDataFunDll.MisDataFun.hashtable_MesServerCode, out MisDataFunDll.MisDataFun.hashtable_MesDll);
            MisDataFunDll.MisDataFun.GetBaseData_tagTable_TagName(out MisDataFunDll.MisDataFun.hashtable_TagName, out MisDataFunDll.MisDataFun.hashtable_TagTypeTagName);

            FuntionMesRead.GetAlarmInit();

        }

        public void SaveData_Load(object sender, EventArgs e)
        {
            MyLog4Net.MyLogHelper.LogCommit += MyLogHelper_LogCommit;
            MqttLink();
            Thread.Sleep(200);
            var deviceState = MesWorkPlc.StartServer();      //开启监控服务
            timer_TestPLC.Enabled = true;
        }
        /// <summary>
        /// 模拟时，写入质量数据
        /// </summary>
        private void InitBasicDataTagValue()
        {
            if (IsDemoMesServer != 1) return;
            string tagID;
            double tagValue;
            //写工位总合格标志  变量类型代码=21
            for (int i = 0; i < MesWork.PlcLinkForm.dt_BasicData.Rows.Count; i++)
            {
                if (MesWork.PlcLinkForm.dt_BasicData.Rows[i]["变量类型代码"].ToString() == "21")
                {
                    tagID = MesWork.PlcLinkForm.dt_BasicData.Rows[i]["TagID"].ToString();
                    MesServerWork.MIS_BASE.WritePLC(tagID, 1);
                }

            }
            if (MesServerWork.MIS_BASE.BasicDataTagValue != null)
            {
                for (int i = 0; i < MesServerWork.MIS_BASE.BasicDataTagValue.Rows.Count; i++)
                {

                    try
                    {
                        switch (Convert.ToInt32(MesServerWork.MIS_BASE.BasicDataTagValue.Rows[i]["变量特点"]))
                        {

                            case 7:
                                tagID = MesServerWork.MIS_BASE.BasicDataTagValue.Rows[i]["TagID"].ToString();
                                MesServerWork.MIS_BASE.WritePLC(tagID, 1);
                                break;
                            case 6:
                                tagID = MesServerWork.MIS_BASE.BasicDataTagValue.Rows[i]["TagID"].ToString();
                                tagValue = Convert.ToDouble(MesServerWork.MIS_BASE.BasicDataTagValue.Rows[i]["列位置"]) * 100
                                    + Convert.ToDouble(MesServerWork.MIS_BASE.BasicDataTagValue.Rows[i]["变量排序"]) / 100;
                                MesServerWork.MIS_BASE.WritePLC(tagID, tagValue);
                                break;
                        }
                    }
                    catch { }

                }
            }

        }

        /// <summary>
        /// 初始化comboBox_OpName（工位号）
        /// </summary>
        private void InitcomboBox_OpName()
        {
            //全部工位号
            comboBox_OpName.DataSource = opNameList = MesWork.PlcLinkForm.opNameList;
            toolStripStatusLabel_WorkStationNum.Text = MesWork.PlcLinkForm.opNameList.Count.ToString();
            toolStripStatusLabel_DownLine.Text = toolStripStatusLabel_WorkStationNum.Text;
        }
        private void Init_dataGridView_CheckOpName()
        {
            DataTable dt;
            DataTable dt1;
            try
            {
                //dt = BaseDataSystemMES.GetCheckOpName_BQ();
                //dataGridView_CheckOpName.DataSource = dt;

                dt1 = BaseDataSystemMES.GetCheckOpName();
                comboBox_OpNameList.DataSource = dt1;
                comboBox_OpNameList.ValueMember = "工位号";
                comboBox_OpNameList.DisplayMember = "工位号";
            }
            catch (Exception ex) { }

        }


        #region mqtt相关
        private void MqttLink()
        {
            List<MqttTopicFilter> TopicFilterList = new List<MqttTopicFilter>();
            string url;
            //string topicMqttTargetTopicPLC;
            //string topicMqttTargetTopicTagTypeCodeID;
            string TopicList;
            string[] TopicListFunItems;
            string[] TopicListItems;
            url = ConfigurationManager.AppSettings["MqttUrl"];
            TopicList = ConfigurationManager.AppSettings["TopicList"];
            TopicListItems = TopicList.Split('|');
            for (int i = 0; i < TopicListItems.Length; i++)
            {
                TopicListFunItems = TopicListItems[i].Split(',');
                hashtableTopicList.Add(TopicListFunItems[0], TopicListFunItems[1]);
            }

            MesWorkMqtt.Mqtt.StartAsync();

            foreach (var topic in TopicListItems)
            {
                TopicListFunItems = topic.Split(',');

                MesWorkMqtt.Mqtt.mqttClient.SubscribeAsync(new MqttTopicFilter { Topic = TopicListFunItems[0] });
            }
            MesWorkMqtt.Mqtt.mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
            MesWorkMqtt.Mqtt.mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
            MesWorkMqtt.Mqtt.mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnSubscriberMessageReceived);

        }
        private string Hello_You_All_Never_Know(string[] args)
        {
            return Guid.NewGuid().ToString();
            //return string.Empty;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        private void OnSubscriberConnected(MqttClientConnectedEventArgs x)
        {
            MyLog4Net.MyLogHelper.Info("Mqtt：", "Mqtt连接成功！");
            OnLineMqtt = true;
            // var rec = x.AuthenticateResult.ResultCode.ToString();
            // label_State.Text = rec;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        private void OnSubscriberDisconnected(MqttClientDisconnectedEventArgs x)
        {
            //var rec = x.AuthenticateResult.ResultCode.ToString();
            try
            {
                MyLog4Net.MyLogHelper.Error("Mqtt：", "Mqtt断开连接！Reason：" + x.Reason);
                OnLineMqtt = false;
            }
            catch (Exception err)
            {

            }
            //label_State.Text = rec;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        public void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
        {
            //var rec = x.ApplicationMessage.ConvertPayloadToString();
            // txt_Rec.Text = txt_Rec.Text + rec + System.Environment.NewLine;
            ThreadPool.QueueUserWorkItem(MIS_Funtion_WEB, x);
        }
        #endregion

        /// <summary>
        /// mqtt 接收web和barcode数据
        /// </summary>
        /// <param name="e"></param>
        public void MIS_Funtion_WEB(object e)
        {
            try
            {
                MqttApplicationMessageReceivedEventArgs x = (MqttApplicationMessageReceivedEventArgs)e;
                var rec = x.ApplicationMessage.ConvertPayloadToString();
                MisDataFunDll.MisDataFun.TransferInfToMES(rec);
            }
            catch (Exception ex)
            {
                //MIS_Funtion(topicFunItem, "Exception:" + ex.Message);
            }

        }
        /// <summary>
        /// 接收内部PLC数据变化 
        /// </summary>
        /// <param name="e"></param>
        public void MIS_Funtion_PLC(object e)
        {
            var rec = e.ToString();
            try
            {
                MisDataFunDll.MisDataFun.TransferInfToMES(rec);
            }
            catch (Exception ex)
            {
                //MIS_Funtion(topicFunItem, "Exception:" + ex.Message);
            }
        }
       

        static public void TagTypeCodeID_Insert(string opName, string TagTypeCodeID, string TagID, string TagValue, DateTime arrivedTime, DateTime leavedTime, int TimeDiff)
        {
            string procedureName;
            procedureName = "测量数据设备状态日志_增加数据";
            SqlParameter[] thisParms = new SqlParameter[7];
            thisParms[0] = new System.Data.SqlClient.SqlParameter("@工位号", opName);
            thisParms[1] = new System.Data.SqlClient.SqlParameter("@信号类型代码", TagTypeCodeID);
            thisParms[2] = new System.Data.SqlClient.SqlParameter("@TagID", TagID);
            thisParms[3] = new System.Data.SqlClient.SqlParameter("@TagValue", TagValue);
            thisParms[4] = new System.Data.SqlClient.SqlParameter("@到达时间", arrivedTime);
            thisParms[5] = new System.Data.SqlClient.SqlParameter("@离开时间", leavedTime);
            thisParms[6] = new System.Data.SqlClient.SqlParameter("@在线时间", TimeDiff);
            DataAccess2.ExecuteStoredProcedure(procedureName, ref thisParms);
        }
   
        private void MisDataFun_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("您确认要退出MES程序吗？该操作会停止MES进行数据处理！", "", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {
                // 关闭Web API服务器
                if (initServer != null)
                {
                    initServer.Close();
                }
                Process.GetCurrentProcess().Kill();
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void timer_Status_Tick(object sender, EventArgs e)
        {
            timer_Status.Enabled = false;
            btn_MqttStatus.BackColor = OnLineMqtt ? Color.Green : Color.Red;

            timer_Status.Enabled = true;
        }
        private void MyLogHelper_LogCommit(object sender, MyLog4Net.MyLogEventArgs e)
        {
            var module = e.Module;
            var message = e.Message;

            var log = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + " " + module + " " + message + "\r\n";
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() =>
                {
                    this.richTextBox1_mqtt.AppendText(log);
                    this.richTextBox1_mqtt.Focus();
                }));
            }
            else
            {
                this.richTextBox1_mqtt.AppendText(log);
                this.richTextBox1_mqtt.Focus();
            }

        }
     



        public void OPCTagData_TagDataOnChange(OpcData.CustomeEvetnArgs e)
        {

            // 处理MIS业务 保存数据
            // ThreadPool.QueueUserWorkItem(Function.MIS_Funtion, e);
            // 处理MES业务 Function
            ThreadPool.QueueUserWorkItem(TagData_MisData_TagDataOnChangeCustomeEvetnArgs, e);
            //ThreadPool.QueueUserWorkItem(TagData_MisData_TagDataOnChange, e);
            // 设备状态日志
            ThreadPool.QueueUserWorkItem(TagTypeCodeID_TagDataOnChange, e);
            //发送通讯服务器  MES web界面显示用 加工位号
            ThreadPool.QueueUserWorkItem(TransferInfToWebServer, e);
            //改变控件状态
            //showMessagePLCInvoke(e);
            //更新状态窗口控件状态
            //ExcutePlcChange(e);
        }
        /// <summary>
        /// 发送信号变化到function
        /// </summary>
        /// <param name="msgEvent"></param>
        private void TagData_MisData_TagDataOnChangeCustomeEvetnArgs(object msgEvent)
        {

            try
            {
                OpcData.CustomeEvetnArgs e = (OpcData.CustomeEvetnArgs)msgEvent;
                string OpName = e.OpName.ToString();//工位号
                string MesCode = e.TagType.ToString();//变量类型代码
                object tagValue = e.TagValue;//变量（0或者1）
                string TagTypeCodeID = e.TagTypeCodeID.ToString();//变量类型代码
                string TagID = e.TagID.ToString();
                string cmd = "";
                cmd = MIS_BASE.hashtable_TagTypeTagName[MesCode];
                string mesServerdllName;

                mesServerdllName = GetMesServeDllByOpName(OpName);
                string fun = "fun_" + cmd;
                int mesServerCode;
                mesServerCode = GetMesServerCodeByOpName(OpName);
                string rvMsg = Newtonsoft.Json.JsonConvert.SerializeObject(e);

                string msg;
                if (cmd == null)
                {
                    cmd = MesCode;
                    msg = $"PLC|{cmd}|{OpName}|{rvMsg}";
                }
                else
                {
                    msg = $"PLC|{cmd}|{OpName}|{rvMsg}";
                }
                try
                {
                    if (TagTypeCodeID == "14")
                    {
                        MesServerWork.MIS_BASE.WritePLC(15, OpName, tagValue);
                        return;
                    }
                    if (TagTypeCodeID == "103")
                    {
                        FuntionMesRead.Send_AlarmMsg(TagID, tagValue.ToString());
                    }
                }
                catch (Exception err)
                {
                    return;
                }
                MIS_Funtion_PLC(msg);
                // asyncSendMessagePLC(mesServerdllName, msg, OpName);
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, "TagData_Lable_TagDataOnChange");
            }
        }

        /// <summary>
        /// 根据工位号获取MesServerCode
        /// </summary>
        /// <param name="OpName"></param>
        /// <returns></returns>
        private static int GetMesServerCodeByOpName(string OpName)
        {
            try
            {
                if (MesServerWork.MIS_BASE.hashtable_MesServerCode.ContainsKey(OpName))
                {
                    return Convert.ToInt32(MesServerWork.MIS_BASE.hashtable_MesServerCode[OpName]);
                }
                return 0;
            }
            catch
            {
                return 0;
            }
        }
        /// <summary>
        /// 根据工位号获取MesServerDll
        /// </summary>
        /// <param name="OpName"></param>
        /// <returns></returns>
        private static string GetMesServeDllByOpName(string OpName)
        {
            try
            {
                if (MesServerWork.MIS_BASE.hashtable_MesDll.ContainsKey(OpName))
                {
                    return MesServerWork.MIS_BASE.hashtable_MesDll[OpName].ToString();
                }
                return "";
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, "GetMesServeDllByOpName");
                return "";
            }
        }
        /// <summary>
        /// 数据库记录信号变化
        /// </summary>
        /// <param name="msg"></param>
        private void TagTypeCodeID_TagDataOnChange(object msgEvent)
        {
            if (IsRecordTagStatus != "1") return;

            try
            {
                CustomeEvetnArgs e = (CustomeEvetnArgs)msgEvent;

                string tagValue;
                if (e.TagValue == null) return;

                switch (e.TagValue.ToString().ToLower())
                {
                    case "1":
                    case "true":
                        tagValue = "1";
                        break;
                    default:
                        tagValue = "0";
                        break;
                }

                string TagTypeCodeID;
                string opName;
                string TagID;
                string TagValue;
                DateTime arrivedTime;
                DateTime leavedTime;
                int TimeDiff;
                opName = e.OpName.ToString();
                TagValue = tagValue;
                TagTypeCodeID = e.TagTypeCodeID.ToString();
                TagID = e.TagID.ToString();
                leavedTime = Convert.ToDateTime(e.TimeStamp);
                arrivedTime = Convert.ToDateTime(e.TimeStampBefore);
                TimeDiff = Convert.ToInt32(e.TagKeepTime);

                if (TagTypeCodeID != "14" && TagTypeCodeID != "15")
                {
                    TagTypeCodeID_Insert(opName, TagTypeCodeID, TagID, TagValue, arrivedTime, leavedTime, TimeDiff);
                }
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, "TagTypeCodeID_TagDataOnChange");
            }

        }
        /// <summary>
        /// 向MES通讯服务器发送消息
        /// </summary>
        /// <param name="msg"></param>
        private void TransferInfToWebServer(object msg1)
        {
            int tagType;
            string opName;
            OpcData.CustomeEvetnArgs msgEvent = (OpcData.CustomeEvetnArgs)msg1;
            //e值不能为空
            if (msgEvent.TagValue == null) return;
            tagType = Convert.ToInt32(msgEvent.TagType);
            opName = msgEvent.OpName.ToString();

            if (!MesServerWork.MIS_BASE.m_WorkStart_OpName.ContainsKey(opName)) return;  //当前系统是否存在该工位 

            string cmd;
            string tagValue;
            string msgSvr;
            try
            {
                switch (Convert.ToInt32(msgEvent.TagValueType))
                {
                    case 11:
                        tagValue = (Convert.ToInt32(msgEvent.TagValue)).ToString();
                        break;
                    default:
                        tagValue = msgEvent.TagValue.ToString();
                        break;
                }
                cmd = MIS_BASE.hashtable_TagTypeTagName[tagType.ToString()];
                if (Convert.ToInt32(MIS_BASE.hashtable_WebTagTypeChange[cmd]) == 0 && MIS_BASE.hashtable_WebTagTypeChange[cmd] != null) return;

                if (cmd != "" && cmd != null)
                {
                    msgSvr = "MES|" + cmd + "|" + opName + "|" + tagValue;
                }
                else
                {
                    return;
                }
                //MES web界面显示用
                MesServerWork.MIS_BASE.asyncSendMessageQos0(msgSvr);
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, "TransferInfToWebServer");
            }
        }
        MesWork.OpcForm opcForm = null;

        public static string WorkStationNum_Now;
        static bool ReadQualityRunning = false;
        static Thread ReadQuality_t = null;
        private void button_ReadData_Click(object sender, EventArgs e)
        {
            if (loadFinish)
            {
                ReadQualityData(WorkStationNum_Now);
            }
        }
        private void ReadQualityData(string opName)
        {
            try
            {
                if (ReadQualityRunning) return;
                ReadQualityRunning = true;
                QualityDataQueryStruct QltyQueryStr = new QualityDataQueryStruct(opName, listView_ShowQualityData);
                //ReadQualityData_Thread(QltyQueryStr);
                ReadQuality_t = new Thread(new ParameterizedThreadStart(ReadQualityData_Thread));
                ReadQuality_t.Start(QltyQueryStr);



                //if (ReadQualityRunning) return;
                //ReadQualityRunning = true;
                //QualityDataQueryStruct QltyQueryStr = new QualityDataQueryStruct(opName, listView_ShowQualityData);

                //ReadQuality_t = new Thread(new ParameterizedThreadStart(ReadQualityData_Thread));
                //ReadQuality_t.Start(QltyQueryStr);

            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, err.Message);

            }
        }
        void ReadQualityData_Thread(object obj)
        {

            int fTime = 0;
            try
            {

                QualityDataQueryStruct QualityStruct = (QualityDataQueryStruct)obj;

                ListView listViewTemp = (ListView)QualityStruct.Ctrl;
                ListViewItem listViewItem = null;
                string[] listViewItemString = new string[5];
                if (listViewTemp.InvokeRequired)
                {
                    Action ActionDelegate = () => { listViewTemp.Items.Clear(); };
                    listViewTemp.Invoke(ActionDelegate);
                }
                else
                {
                    listViewTemp.Items.Clear();
                }
                //System.Collections.Concurrent.ConcurrentDictionary<string, object> cd = null;
                IEnumerable cd = null;
                //IEnumerable<string,object> items;
                string opName = QualityStruct.OpName;
                var opTagList = GetDbAndMaxLengthByOpNameByBytes(opName);
                //TagID 排序
                //var cd_OpName = opTagList.OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);
                //全部数据
                var cd_OpName = from r in opTagList
                                orderby r.Key
                                select r;

                //质量数据
                var query_Qd = from r in opTagList

                               where ((OpcBasic.TagFormat)r.Value).TagTypeCodeID == 105

                               orderby r.Key

                               select r;
                //监控变量
                var query_Monitor = from r in opTagList

                                    where ((OpcBasic.TagFormat)r.Value).TagTypeCodeID != 105

                                    orderby r.Key

                                    select r;

                if (cb_MonitorData.Checked)
                {
                    cd = query_Monitor;
                    //cd = MesWork.PlcLinkForm.ReadPLC_GroupMonitor(QualityStruct.OpName);
                }
                if (cb_QdData.Checked)
                {
                    cd = query_Qd;
                    //cd = MesWork.PlcLinkForm.ReadPLC_GroupData_Qd(QualityStruct.OpName);
                }
                if (cb_MonitorData.Checked == false & cb_QdData.Checked == false)
                {
                    cd = cd_OpName;

                    //cd = MesWork.PlcLinkForm.ReadPLC_GroupData(QualityStruct.OpName);
                }
                if (cb_MonitorData.Checked == true & cb_QdData.Checked == true)
                {
                    cd = cd_OpName;
                    //cd = MesWork.PlcLinkForm.ReadPLC_GroupData(QualityStruct.OpName);
                }

                //排序
                var result2 = cd;// from pair in cd orderby pair.Key select pair;
                ThisWorkStationData = new BasicData.QualityDataType[1000];

                foreach (KeyValuePair<string, object> _cd in result2)
                {
                    var tagID = _cd.Key;
                    var TF = (OpcBasic.TagFormat)_cd.Value;

                    listViewItemString[0] = TF.TagID;
                    listViewItemString[1] = TF.ItemName;
                    listViewItemString[2] = TF.TagValue.ToString();
                    listViewItemString[3] = TF.OpName;
                    listViewItemString[4] = "(" + TF.TagType + ")" + TF.TagDbAndStartAdrWrite.ToString();

                    listViewItem = new ListViewItem(listViewItemString);
                    if (TF.IsMonitor == 1)
                    {
                        listViewItem.BackColor = Color.LimeGreen;
                    }
                    if (listViewTemp.InvokeRequired)
                    {
                        Action<ListViewItem> ActionDelegate = (x) => { listViewTemp.Items.Add(x); };
                        listViewTemp.BeginInvoke(ActionDelegate, listViewItem);
                    }
                    else
                    {
                        listViewTemp.Items.Add(listViewItem);
                    }
                    ThisWorkStationData[fTime].opName = TF.OpName;
                    ThisWorkStationData[fTime].tagID = TF.TagID;
                    ThisWorkStationData[fTime].tagTypeID = TF.TagTypeID;
                    ThisWorkStationData[fTime].tagValue = TF.TagValue;
                    fTime++;
                }

                ReadQualityRunning = false;
            }
            catch (Exception err)
            {
                ReadQualityRunning = false;
                ApplicationLog.WriteLog(err, err.Message);

            }
        }
        private ConcurrentDictionary<string, object> GetDbAndMaxLengthByOpNameByBytes(string opName)
        {
            string tagStartAdr = "";
            ushort tagAdrListMaxLength = 0;
            PlcLinkForm.GetDbAndMaxLengthByOpName(opName, out tagStartAdr, out tagAdrListMaxLength);
            var tagAdrListTagFormat = PlcLinkForm.ReadQualityDataList(opName, tagStartAdr, tagAdrListMaxLength);
            return tagAdrListTagFormat;
        }

        private void comboBox_OpName_SelectedIndexChanged(object sender, EventArgs e)
        {
            //此处需要异步查询当前工位在线状态
            try
            {
                if (AllowLoad)
                {
                    WorkStationNum_Now = comboBox_OpName.SelectedValue.ToString();
                }

            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, err.Message);
            }
        }

        private void listView_ShowQualityData_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                BasicData.QualityDataType SelectData = new BasicData.QualityDataType();
                ListView.SelectedIndexCollection index = new ListView.SelectedIndexCollection(listView_ShowQualityData);
                SelectData = ThisWorkStationData[index[0]];
                WriteQualityValueForm WriteForm = new WriteQualityValueForm(SelectData, this);
                WriteForm.ShowDialog();
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, err.Message);

            }
        }

        private void ToolStripMenuItem_PlcDebug_Click(object sender, EventArgs e)
        {
            if (opcForm != null)
            {
                opcForm.Close();
                opcForm.Dispose();
                opcForm = null;
            }

            opcForm = new MesWork.OpcForm(IsDemoMesServer);
            opcForm.Show();
        }

        private void 修改配置文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new AppConfigSetting.AppConfigSetForm().ShowDialog();
        }
        /// <summary>
        /// 关于迈思按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 关于迈思ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.meswork.com");
        }
        /// <summary>
        /// 版本信息按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 版本信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            VersionsInformation VersionForm = new VersionsInformation();
            VersionForm.ShowDialog();
        }
        private void timer_TestPLC_Tick(object sender, EventArgs e)
        {
            try
            {
                if (!AllowLoad) return;
                timer_TestPLC.Enabled = false;
                Runtime_Thread();

                timer_TestPLC.Enabled = true;

                //SystemFramework.SystemClock.SystemClockTimerTick();
            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, err.Message);
            }
        }
        void RefreshPlcConnectStatus(object sender, EventArgs e)
        {
            try
            {
                toolStripStatusLabel_OnlineNum.Text = sender.ToString();
                toolStripStatusLabel_DownLine.Text = (Convert.ToInt32(toolStripStatusLabel_WorkStationNum.Text) - Convert.ToInt32(sender.ToString())).ToString();

            }
            catch (Exception err)
            {
                ApplicationLog.WriteLog(err, err.Message);

            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            FuntionMesRead.GetAlarmInit();
            MyLog4Net.MyLogHelper.Info($"报警更新：", "报警信息更新完成！");
        }

        private void CheckA10ReadOverStart_Click(object sender, EventArgs e)
        {
            if(CheckA10ReadIverStart())
            {
                MIS_BASE.WritePLC(20, "OPA10", false);
                MIS_BASE.WritePLC(7, "OPA10", false);
                MyLog4Net.MyLogHelper.Info($"A10异常状态恢复：", "A10异常状态恢复完成！");
            }
            else
            {
                MyLog4Net.MyLogHelper.Info($"A10异常状态恢复：", "A10异常状态获取错误！");
            }
        }

        private bool CheckA10ReadIverStart()
        {
            // 再去查一下A10 的上线工位状态 20 保存完成 7 工作完成  19 质量数据可以读
            string checkOpName = "OPA10";
            bool isError = false;
            MIS_BASE.Read_TagTypeID(20, checkOpName, out string mesReadOver);
            MIS_BASE.Read_TagTypeID(7, checkOpName, out string mesWorkOver);
            MIS_BASE.Read_TagTypeID(19, checkOpName, out string plcIsRead);

            if (plcIsRead == "0")
            {
                isError = (mesReadOver == "1" || mesWorkOver == "1");
            }
            return isError;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MIS_BASE.Write_EngineTypeGetOver_MES(comboBox_OpName.SelectedValue.ToString(), true);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            MIS_BASE.Write_EngineTypeGetOver_MES(comboBox_OpName.SelectedValue.ToString(), false);
        }

        /// <summary>
        /// 界面上的开启时间
        /// </summary>
        void Runtime_Thread()
        {
            DateTime Now = DateTime.Now;
            TimeSpan x = Now.Subtract(StartTime);
            toolStripStatusLabel_RunTime.Text = x.Days.ToString() + "天" + x.Hours.ToString("00") + "小时" + x.Minutes.ToString("00") + "分" + x.Seconds.ToString("00") + "秒";
            //Thread t = new Thread(new ParameterizedThreadStart (Runtime));
            //t.Start(toolStripStatusLabel_RunTime);
        }

    }


}
