public void ThreadPool_Proc_Virtual(string msg)
        {
            try
            {
                cls_read_data_reply CollectData = null;
                CollectData = JsonConvert.DeserializeObject <cls_read_data_reply>(msg.ToString());

                cls_ProcRecv_CollectData ProcRecv_CollectData = new cls_ProcRecv_CollectData();
                ProcRecv_CollectData.GateWayID = _GatewayID;
                ProcRecv_CollectData.Device_ID = _DeviceID;

                if (CollectData != null)
                {
                    // 直接平行處理對應所有Tag
                    Parallel.ForEach(CollectData.EDC_Data, p =>
                    {
                        ProcRecv_CollectData.Prod_EDC_Data.Enqueue(Tuple.Create(p.DATA_NAME, p.DATA_VALUE));
                    });
                }

                this.Put_ProcRecv_CollectData(ProcRecv_CollectData);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Handle ProcCollectData Message Error [{0}].", ex.Message));
            }
        }
        public void SetOnlineMonitorEDCReportStatus(string gw_id, string dv_id, string payload)
        {
            if (ObjectManager.MonitorManager != null)
            {
                //cls_Monitor_Gateway_Info gw = ObjectManager.MonitorManager.monitor_list.Where(p => p.gateway_id == gw_id).FirstOrDefault();
                //if (gw != null)
                //{
                //cls_Monitor_Device_Info dv = gw.device_list.Where(p => p.device_id == dv_id).FirstOrDefault();
                cls_Monitor_Device_Info mdv = ObjectManager.MonitorManager.device_list.Where(o => o.gateway_id == gw_id && o.device_id == dv_id).FirstOrDefault();
                if (mdv != null)
                {
                    cls_HeartBeat hb = new cls_HeartBeat();

                    cls_read_data_reply CollectData = null;
                    CollectData       = JsonConvert.DeserializeObject <cls_read_data_reply>(payload);
                    mdv.last_edc_time = DateTime.ParseExact(CollectData.Time_Stamp, "yyyyMMddHHmmssfff", CultureInfo.InvariantCulture);

                    mdv.last_edc_time = DateTime.ParseExact(CollectData.Time_Stamp, "yyyyMMddHHmmssfff", CultureInfo.InvariantCulture);
                }
                //}
            }
        }
        public void ThreadPool_Proc_Physical(string msg)
        {
            try
            {
                cls_read_data_reply CollectData = null;
                CollectData = JsonConvert.DeserializeObject <cls_read_data_reply>(msg.ToString());

                cls_ProcRecv_CollectData ProcRecv_CollectData = new cls_ProcRecv_CollectData();
                ProcRecv_CollectData.GateWayID = _GatewayID;
                ProcRecv_CollectData.Device_ID = _DeviceID;

                if (CollectData != null)
                {
                    // 直接平行處理對應所有Tag
                    Parallel.ForEach(CollectData.EDC_Data, p =>
                    {
                        cls_Tag Device_Tag = _Device.tag_info[p.DATA_NAME];
                        string Tag_Value   = p.DATA_VALUE;
                        int BitPoints      = 0;
                        double tmp_output  = 0;
                        string Output      = string.Empty;

                        if (Device_Tag.Type == "PLC")
                        {
                            if (CheckWordType.Any(x => Device_Tag.UUID_Address.Contains(x)))
                            {
                                if (Tag_Value.Length % 4 != 0)
                                {
                                    return;
                                }
                                switch (Device_Tag.Expression)
                                {
                                case "BIT":
                                    BitPoints = CalcBitPoints(Device_Tag.UUID_Address);
                                    if (BitPoints != 0)
                                    {
                                        Output = HexToBit(0, BitPoints, Tag_Value);
                                    }
                                    else
                                    {
                                        Output = string.Empty;
                                    }
                                    break;

                                case "UINT":
                                    BitPoints  = 16;      // Int固定16 bit ;
                                    tmp_output = HexToInt(BitPoints, Tag_Value);
                                    tmp_output = (Device_Tag.scale * tmp_output) + Device_Tag.offset;
                                    Output     = tmp_output.ToString();
                                    break;

                                case "ULONG":
                                    BitPoints  = 32;
                                    tmp_output = HexToLong(BitPoints, Tag_Value);
                                    tmp_output = (Device_Tag.scale * tmp_output) + Device_Tag.offset;
                                    Output     = tmp_output.ToString();
                                    break;

                                case "SINT":
                                    BitPoints  = 16;
                                    tmp_output = HexToSInt(BitPoints, Tag_Value);
                                    tmp_output = (Device_Tag.scale * tmp_output) + Device_Tag.offset;
                                    Output     = tmp_output.ToString();
                                    break;

                                case "SLONG":
                                    BitPoints  = 32;
                                    tmp_output = HexToSLong(BitPoints, Tag_Value);
                                    tmp_output = (Device_Tag.scale * tmp_output) + Device_Tag.offset;
                                    Output     = tmp_output.ToString();
                                    break;

                                case "ASC":
                                    Output = HexToASCII(Tag_Value);      //  目前Decode 全部都解析解析完再考慮長度
                                    break;

                                default:
                                    Output = string.Empty;
                                    break;
                                }
                            }
                        }

                        if (Output != string.Empty)
                        {
                            ProcRecv_CollectData.Prod_EDC_Data.Enqueue(Tuple.Create(p.DATA_NAME, Output));
                        }
                    });
                }

                this.Put_ProcRecv_CollectData(ProcRecv_CollectData);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Handle ProcCollectData Message Error [{0}].", ex.Message));
            }
        }