using CommonClassLib;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DBFactory;
using HandyControl.Controls;
using Microsoft.VisualBasic;
using ModuleTech;
using ModuleTech.Gen2;
using Newtonsoft.Json;
using ReaderManager.Models;
using RFIDReaderTC.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Runtime;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using System.Xml;
namespace RFIDReaderTC.ViewModel
{
    public partial class MainWindowViewModel: ObservableObject
    {

        public Reader? rdr;
        /// <summary>
        /// 定时器 监听GPI 状态  false为读取状态 true为空闲状态
        /// </summary>
        System.Timers.Timer? timer;

        //服务地址
        //RGDWCSService.RGDWCSServiceClient service = new RGDWCSService.RGDWCSServiceClient();

        /// <summary>
        /// 设置页面是否显示
        /// </summary>
        [ObservableProperty]
        private bool menuView;

        /// <summary>
        /// 调度服务连接状态
        /// </summary>
        [ObservableProperty]
        private bool dispatchState;

        /// <summary>
        /// 读写器连接状态
        /// </summary>
        [ObservableProperty]
        private bool readerState;

        [ObservableProperty]
        private bool readIsOpen;
        /// <summary>
        /// 是否允许手动操作
        /// </summary>
        [ObservableProperty]
        private bool readerPerson;

        /// <summary>
        /// 箱条码数据
        /// </summary>
        [ObservableProperty]
        private FlowDocument richText = new FlowDocument();

        /// <summary>
        /// 箱条码数据
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<TagInfo> tagInfos = new ObservableCollection<TagInfo>();

        /// <summary>
        /// 表条码数据
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<TagInfo> goodsTagInfos = new ObservableCollection<TagInfo>();


        /// <summary>
        /// 读取数量
        /// </summary>
        public string LbTagsCount => "读取数量: " + TagInfos.Count;

        /// <summary>
        /// 读取数量
        /// </summary>
        public string LbGoodsTagsCount => "读取数量: " + GoodsTagInfos.Count;


        #region 配置相关
        [ObservableProperty]
        private string antenna1 = GetSetting("Antenna1");
        [ObservableProperty]
        private string antenna2 = GetSetting("Antenna2");
        [ObservableProperty]
        private string antenna3 = GetSetting("Antenna3");
        [ObservableProperty]
        private string antenna4 = GetSetting("Antenna4");
        [ObservableProperty]
        private string antenna5 = GetSetting("Antenna5");
        [ObservableProperty]
        private string antenna6 = GetSetting("Antenna6");
        [ObservableProperty]
        private string antenna7 = GetSetting("Antenna7");
        [ObservableProperty]
        private string antenna8 = GetSetting("Antenna8");
        [ObservableProperty]
        private string readUrl = GetSetting("ReadUrl");
        [ObservableProperty]
        private string uploadPath = GetSetting("UploadPath");
        [ObservableProperty]
        private string dispatchPath = GetSetting("DispatchPath");
        [ObservableProperty]
        private string lEDPath = GetSetting("LEDPath");

        public void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            try
            {
                e.Handled = new Regex("[^0-9]+").IsMatch(e.Text);
                if (!e.Handled)
                {
                    System.Windows.Controls.TextBox textBox = sender as System.Windows.Controls.TextBox;
                    string currentText = textBox.Text;

                    // 当前输入的文本位置
                    int selectionStart = textBox.SelectionStart;
                    int selectionLength = textBox.SelectionLength;

                    // 预测输入后的文本
                    string newText = currentText.Remove(selectionStart, selectionLength).Insert(selectionStart, e.Text);

                    if (int.TryParse(newText, out int result))
                    {
                        // 限制输入值在 0 到 3300 之间
                        if (result < 0 || result > 3300)
                        {
                            e.Handled = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        #endregion

        #region botton绑定事件

        [RelayCommand]
        private void ButtonSave()
        {
            try
            {

               SetSetting("Antenna1", Antenna1);
               SetSetting("Antenna2", Antenna2);
               SetSetting("Antenna3", Antenna3);
               SetSetting("Antenna4", Antenna4);
               SetSetting("Antenna5", Antenna5);
               SetSetting("Antenna6", Antenna6);
               SetSetting("Antenna7", Antenna7);
               SetSetting("Antenna8", Antenna8);

               SetSetting("ReadUrl", ReadUrl);
               SetSetting("UploadPath", UploadPath);
               SetSetting("DispatchPath", DispatchPath);
               SetSetting("LEDPath", LEDPath);

              App.Restart();

            }
            catch (Exception ex)
            {

            }
        }
        [RelayCommand]
        private void ButtonReadOpen()
        {
            TagInfos.Clear();
            GoodsTagInfos.Clear();
            try
            {
                rdr.StartReading();
                ReadIsOpen = true;
            }
            catch (Exception ex)
            {
            }

        }

        [RelayCommand]
        private void ButtonReadClose()
        {
            rdr.StopReading();
            ReadIsOpen = false;
            MessageBoxResult result = HandyControl.Controls.MessageBox.Show(
                               "是否需要进行数据上传？",  // 提示信息
                               "确认",                     // 窗口标题
                               MessageBoxButton.YesNo,     // 按钮选择
                               MessageBoxImage.Question    // 图标样式
                           );

            if (result == MessageBoxResult.Yes)
            {
                string sR = string.Empty;
                LEDHelper.refreshScanScreen(TagInfos.Count.ToString(), GoodsTagInfos.Count.ToString(), LEDPath, out sR);
                submitData();
                TxtAdd("");
            }
        }
        [RelayCommand]
        private void ButtonMenuView()
        {
            if (MenuView)
            {
                MenuView = false;
            }
            else
            {
                MenuView = true;
            }
        }
        [RelayCommand]
        private void ButtonAdd()
        {
            try
            {
                TxtAdd("11111");

            }
            catch (Exception ex)
            {

            }
        }
        [RelayCommand]
        private void ButtonConnect()
        {
            try
            {
                OpenReader();
            }
            catch (Exception ex)
            {

            }
        }

        #endregion


        static DBOperator dbo = new DBOperator();
        public ServiceReference1.RGDWCSServiceClient _I_RFID;
        MainWindow main;
        public MainWindowViewModel(MainWindow mn)
        {
            ReaderPerson = true;
            ReadIsOpen = false;
            main = mn;
            tagInfos.CollectionChanged -= TagInfos_CollectionChanged;
            goodsTagInfos.CollectionChanged += TagInfos_CollectionChanged;
            //读写器初始化
            Task.Run(() =>
            {
                ReaderState = OpenReader();
                if (ReaderState)
                {
                    //读写器状态监听
                    timer = new System.Timers.Timer(300);
                    timer.Elapsed += Timer_Elapsed;
                    timer.Start();
                }
            });
            Task.Run(() =>
            {
                _I_RFID = new ServiceReference1.RGDWCSServiceClient();
                WebServerInint();

                ListenDll.LV_InitDllEx(0);
                string sR = string.Empty;
                LEDHelper.refreshScanScreen("0", "0", LEDPath, out sR);
            });
            timer_Read = new System.Threading.Timer(ProcessTags, null, Timeout.Infinite, 300);

        }
        public async void WebServerInint()
        {
            try
            {
                await this._I_RFID.RFIDReadyToReadAsync("12002");
                DispatchState = true;
            }
            catch (Exception ex)
            {
                DispatchState = false;
            }
        }
        /// <summary>
        /// 显示信息
        /// </summary>
        public void TxtAdd(string txt)
        {
            // 获取当前 FlowDocument
            FlowDocument document = RichText;

            // 创建一个新的 Paragraph
            Paragraph newParagraph = new Paragraph();

            Run normalText = new Run("上传时间："+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            normalText.Foreground = Brushes.Black;
            normalText.FontWeight = FontWeights.Bold; // 设置加粗
            newParagraph.Inlines.Add(normalText);
            newParagraph.Inlines.Add(new LineBreak());
            newParagraph.Inlines.Add(new LineBreak());

            Run boldText = new Run("-----------箱条码-----------");
            boldText.FontWeight = FontWeights.Bold; // 设置加粗
            newParagraph.Inlines.Add(boldText);
            newParagraph.Inlines.Add(new LineBreak());

            Run box = new Run(JsonConvert.SerializeObject(TagInfos));
            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            newParagraph.Inlines.Add(box);

            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            Run goodsText = new Run("-----------表条码-----------");
            goodsText.FontWeight = FontWeights.Bold;
            newParagraph.Inlines.Add(goodsText);

            newParagraph.Inlines.Add(new LineBreak());
            newParagraph.Inlines.Add(new LineBreak());
            Run good = new Run(JsonConvert.SerializeObject(GoodsTagInfos));
            newParagraph.Inlines.Add(good);

            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            Run sResult = new Run("-----------上传结果-----------");
            sResult.FontWeight = FontWeights.Bold;
            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            newParagraph.Inlines.Add(sResult);

            Run Result = new Run(txt);
            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符
            newParagraph.Inlines.Add(Result);
            newParagraph.Inlines.Add(new LineBreak());  // 这是一个换行符

            // 将新的 Paragraph 添加到 FlowDocument 中
            document.Blocks.Add(newParagraph);
            // 滚动到最底部
            main.Mesg.ScrollToEnd();
        }
        #region 读写器相关

        private readonly System.Threading.Timer timer_Read;  // 定时器
        private readonly object lockObj = new object();  // 锁对象
        private bool isProcessing = false;  // 定时器是否正在运行

        /// <summary>
        /// 启动定时器
        /// </summary>
        private void StartProcessing()
        {
            lock (lockObj)
            {
                if (!isProcessing)
                {
                    isProcessing = true;
                    // 启动定时器
                    timer_Read.Change(0, 300); // 立即启动并每300毫秒执行一次
                }
            }
        }
        /// <summary>
        /// 停止定时器
        /// </summary>
        private void StopProcessing()
        {
            lock (lockObj)
            {
                if (isProcessing)
                {
                    isProcessing = false;
                    // 停止定时器
                    timer_Read.Change(Timeout.Infinite, 300); // 停止定时器
                }
            }
        }
        private async void ProcessTags(object state)
        {
            List<TagReadData> temp_tags;
            lock (lockObj)
            {
                temp_tags = new List<TagReadData>(tagList);  // 拷贝 tags 数据
                tagList.Clear();  // 清空 tags
            }

            if (temp_tags.Count > 0)
            {
                // 使用并行处理每个 tag
                var tasks = temp_tags.Select(tag =>
                {
                    return Task.Run(() =>
                    {
                        string barcode = tag.EPCString.Replace(" ", "");
                        //24位,后12位有不多余1个非0字符
                        if (barcode.Contains("000000000000") || (barcode.Substring(barcode.Length - 12).Distinct().Count() <= 2))
                        {
                            barcode = barcode.Substring(0, 12);
                            var tagInfo = TagInfos.FirstOrDefault(t => t.Tag == barcode);

                            // 在 UI 线程上修改集合
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                if (tagInfo != null)
                                {
                                    tagInfo.Count += tag.ReadCount;
                                }
                                else
                                {
                                    TagInfo tags = new TagInfo
                                    {
                                        Tag = barcode,
                                        Count = tag.ReadCount
                                    };
                                    TagInfos.Add(tags);
                                }
                            });
                        }
                        else if (barcode.Length >= 22)
                        {
                            barcode = barcode.Substring(0, 22);
                            var tagInfo = GoodsTagInfos.FirstOrDefault(t => t.Tag == barcode);

                            // 在 UI 线程上修改集合
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                if (tagInfo != null)
                                {
                                    tagInfo.Count += tag.ReadCount;
                                }
                                else
                                {
                                    TagInfo tags = new TagInfo
                                    {
                                        Tag = barcode,
                                        Count = tag.ReadCount
                                    };
                                    GoodsTagInfos.Add(tags);
                                }
                            });
                        }
                    });
                }).ToArray();  // 将任务数组化

                // 等待所有任务完成
                await Task.WhenAll(tasks);
            }

            // 如果没有待处理的 tags，停止定时器
            if (tagList.Count == 0)
            {
                StopProcessing();
            }
        }


        private static readonly object TimerLock = new object();
        /// <summary>
        /// 定时器事件监听到射频门状态发生变化后进行收取
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            lock (TimerLock)
            {
                try
                {
                    if (!ReadIsOpen)
                    {
                        var gpistate_temp = rdr.GPIGet(1);
                        if (!gpistate_temp)
                        {
                            timer.Stop();
                            //射频开始采集
                            System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
                            {
                                TagInfos.Clear();
                                GoodsTagInfos.Clear();
                                rdr.StartReading();
                                ReadIsOpen = true;
                                ReaderPerson = false;
                            }));
                            Task.Run(() =>
                            {
                                Object dv = dbo.GetSingle("select F_TASK_TYPE from T_WareHouse");
                                //string TASK_TYPE = dv.ToString();
                                Thread.Sleep(5000);
                                //if (TASK_TYPE == "Inventory")
                                //    Thread.Sleep(5000);
                                //else
                                //    Thread.Sleep(2000);
                                
                                System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
                                {
                                    //射频采集结束
                                    rdr.StopReading();
                                    ReadIsOpen = false;
                                    ReaderPerson = true;

                                    string sR = string.Empty;
                                    LEDHelper.refreshScanScreen(TagInfos.Count.ToString(), GoodsTagInfos.Count.ToString(), LEDPath, out sR);
                                    submitData();
                                    timer.Start();
                                }));
                            });
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    //Environment.Exit(0);
                }
            }
        }
        /// <summary>
        /// 初始化打开
        /// </summary>
        bool OpenReader()
        {
            if (rdr != null)
            {
                rdr.Disconnect();
                rdr = null;
            }

            /*
             * 当使用设备的串口进行连接的时候，Create函数的第一个参数也可能是串口号
             * （例如com1）当设备仅有一个天线端口时（例如一体机或者发卡器），Create
             * 函数的第三个参数也可能为1,读写器出厂默认IP为192.168.1.100 
             * */
            int antnum = 16;
            try
            {
                //rdr = Reader.Create("192.168.0.202", ModuleTech.Region.PRC, antnum);
                rdr = Reader.Create(ReadUrl, ModuleTech.Region.NA, antnum);
            }
            catch (Exception ex)
            {
                return false;
            }

            #region 必须要设置的参数

            #region 设置读写器的发射功率
            //获取读写器最大发射功率
            //int a= ()rdr.ParamGet("RfPowerMax");
            ushort maxp = Convert.ToUInt16(rdr.ParamGet("RfPowerMax"));// rdr.ParamGet("RfPowerMax");
            AntPower[] pwrs = new AntPower[antnum];
            for (int i = 0; i < antnum; ++i)
            {
                pwrs[i].AntId = (byte)(i + 1);//天线id
                pwrs[i].ReadPower = GetReadPower(i + 1);//天线频率
                pwrs[i].WritePower = maxp;
            }
            //设置读写器发射功率,本例设置为最大发射功率，可根据实际情况调整,
            //一般来说，功率越大则识别距离越远
            rdr.ParamSet("AntPowerConf", pwrs);
            #endregion

            #region 设置盘存标签使用的天线
            //如果要使用其它天线可以在数组useants中放置其它多个天线编号，本例中是使用天线1
            int[] useants = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            rdr.ParamSet("ReadPlan", new SimpleReadPlan(TagProtocol.GEN2, useants));
            #endregion

            #region 设置盘存操作的其它细节选项
            BackReadOption bro = new BackReadOption();
            BackReadOption.FastReadTagMetaData frtmdata = new BackReadOption.FastReadTagMetaData();
            /*是否采用高速模式（目前只有slr11xx和slr12xx系列读写器才支持）,对于
            *一般标签数量不大，速度不快的应用没有必要使用高速模式,本例没有设置
            *使用高速模式
            * */
            bro.IsFastRead = true;
            #region 选择使用高速模式才起作用的选项
            //参照如下设置即可,如果使能高速模式，则只需取消以下被注释的代码即可

            //标签信息是否携带识别天线的编号
            frtmdata.IsAntennaID = true;
            //标签信息是否携带标签识别次数
            frtmdata.IsReadCnt = false;
            //标签信息是否携带识别标签时的信号强度
            frtmdata.IsRSSI = false;
            //标签信息是否携带时间戳
            frtmdata.IsTimestamp = false;
            //标签信息是否携带识别标签时的工作频点
            frtmdata.IsFrequency = false;
            //标签信息是否携带识别标签时同时读取的其它bank数据信息,如果要获取在
            //盘存时同时读取其它bank的信息还必须设置EmbededCmdOfInventory参数,
            //（目前只有slr11xx和slr12xx系列读写器才支持）
            frtmdata.IsEmdData = false;
            //保留字段，可始终设置为false
            frtmdata.IsRFU = false;
            //高速模式下为取得最佳效果设置为0即可
            bro.FastReadDutyRation = 0;

            #endregion

            #region 非高速模式才起作用的选项
            /*
            //盘存周期,单位为ms，可根据实际使用的天线个数按照每个天线需要200ms
            //的方式计算得出,如果启用高速模式则此选项没有任何意义，可以设置为
            //任意值，或者干脆不设置
            bro.ReadDuration = (ushort)(200 * useants.Length);
            //盘存周期间的设备不工作时间,单位为ms,一般可设置为0，增加设备不工作
            //时间有利于节电和减少设备发热（针对某些使用电池供电或空间结构不利
            //于散热的情况会有帮助）
            bro.ReadInterval = 0;
            */
            #endregion

            bro.FRTMetadata = frtmdata;
            rdr.ParamSet("BackReadOption", bro);
            SetParams();
            rdr.ParamSet("Ex10FastModeParams", null);
            //rdr.ParamSet("Ex10FastModeParams", new Ex10FastModeParams());
            #endregion

            #endregion

            #region 必须要设置的事件处理函数
            //识别到标签事件的处理函数
            rdr.ReadException += OnReaderException;
            //读写器异常发生事件的处理函数
            rdr.TagsRead += OnTagsRead;
            #endregion

            #region 根据应用需求可能要设置的参数
            //
            #region 设置Gen2Session
            /*
            //标签数量比较大，且移动速度缓慢或静止不动,设置为Session1可取得更
            //好效果,反之标签数量较少移动速度较快应设置为Session0,读写器默认
            //为Session0
            rdr.ParamSet("Gen2Session", Session.Session1);
            */
            rdr.ParamSet("Gen2Session", Session.Session1);
            #endregion

            #region 设置GPI触发控制读写工作
            /*
            //共有三种触发模式：
            //1  预定义两种GPI状态，一种作为触发读写器启动盘存的条件，另一种
            //   作为停止盘存的条件
            //2  预定义一种GPI状态，触发读写器启动盘存，指定一段时间(必须大于
            //   5秒)后自动停止盘存标签
            //3  预定义两种GPI状态，满足任何一种GPI状态都触发读写器启动盘存，
            //   指定一段时间(必须大于5秒)后自动停止盘存标签

            //详见"读写器GPI触发工作模式.pdf"
            //以下示例为模式1，Trigger1State为启动工作时的GPI状态，且可以指
            //定多个GPI的状态，此例指定当GPI1为false时读写器开始盘存,当GPI2
            //为false时读写器停止盘存
            GPITrigger GpiTriiger = new GPITrigger();
            GPIState[] startstates = new GPIState[1];
            startstates[0] = new GPIState(1, false);
            GpiTriiger.Trigger1State = startstates;
            GpiTriiger.TriggerType = GPITriggerType.GPITrigger_Tri1Start_Tri2Stop;

            GPIState[] stopstates = new GPIState[1];
            stopstates[0] = new GPIState(2, false);
            GpiTriiger.Trigger2State = stopstates;
            rdr.ParamSet("BackReadGPITrigger", GpiTriiger);
            //在GPI触发工作时，当触发条件发生时的处理函数，可通过此事件获取触
            //发时刻的GPI状态，如果不关心触发时刻的GPI状态以及时序关系，可以
            //不添加此事件，详见文档"读写器GPI触发工作模式.pdf"
            rdr.GpiTrigger += GpiStateOnTrigger;
            */
            #endregion

            #region 设置盘存标签时的过滤条件
            /*
            //对于某些应用可能需要读写器只盘存符合某些数据特征的标签，
            //可以通过设置过滤条件来实现，这样对于不符合特征的标签就
            //不会被采集，以下代码实现只盘存EPC码以0011（二进制）开头
            //的标签
            string binstr = "0011";
            byte[] fiterdata = ByteFormat.FromBin(binstr);
            Gen2TagFilter filter = new Gen2TagFilter(binstr.Length, fiterdata, MemBank.EPC, 32, false);
            rdr.ParamSet("Singulation", filter);
            */
            #endregion

            #region 设置盘存过程中同时读其它bank数据
            /*
            //有些应用除了快速盘存标签的EPC码外还想同时抓取某一个bank内的
            //数据，可以通过设置此参数实现（目前只有slr11xx和slr12xx系列
            //读写器才支持），以下代码实现抓取tid区从0块开始的12个字节
            //的数据,需要注意的是抓取的字节数必须是2的倍数,如果成功获得其
            //它bank的数据则TagReadData类的成员EbdData则为获得的数据，如果
            //失败的话则EbdData为null
            EmbededCmdData ecd = new EmbededCmdData(MemBank.TID, 0, 12);
            rdr.ParamSet("EmbededCmdOfInventory", ecd);
            */
            #endregion

            #endregion
            return true;
        }
        public void SetParams()
        {
            //rdr.ParamSet("Gen2Target", (ModuleTech.Gen2.Target)12);
            //rdr.ParamSet("Gen2Qvalue", 2);
            rdr.ParamSet("EmbededCmdOfInventory", null);
            rdr.ParamSet("AccessPassword", (uint)0);
            rdr.ParamSet("Gen2Session", (ModuleTech.Gen2.Session)0);
            //rdr.ParamSet("gen2tagEncoding", 111);
        }
        List<TagReadData> tagList = new List<TagReadData>();
        int number = 0;
        /// <summary>
        /// 读写器触发采集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="tagsArgs"></param>
        void OnTagsRead(object sender, Reader.TagsReadEventArgs tagsArgs)
        {
            try
            {
                Reader rdrtmp = (Reader)sender;
                #region 示例在盘存标签事件中做其它标签访问操作
                /*
                //可以对读到的标签做进一步的读，写，锁和GPIO等操作等操作
                //注：只有在非高速盘存模式下才可以进行其它的标签操作，高速盘存模式下禁
                //止再进行其它标签操作，否则盘存操作将被终止，其它的标签操作也不会成功。
                //但GPIO的操作是例外，不论哪种盘存模式都可以在此处操作GPIO
                 * */
                /*
                //以下示例写入两个块的数据到盘存到的标签的USER区中
                foreach (TagReadData tag in tagsArgs.Tags)
                {
                    ushort[] wdata = new ushort[2];
                    wdata[0] = 0x1234;
                    wdata[1] = 0x5678;
                    Gen2TagFilter filter = new Gen2TagFilter(tag.EPC.Length * 8, tag.EPC, MemBank.EPC, 32, false);
                    try
                    {
                        //必须设置操作使用的天线，一般可设置为标签被盘存到时的天线
                        rdrtmp.ParamSet("TagopAntenna", tag.Antenna);
                        rdrtmp.WriteTagMemWords(filter, MemBank.USER, 0, wdata);
                    }
                    catch (System.Exception ex)
                    {
                    //操作有可能失败（很多原因可能造成操作失败，常见的比如标签速度过快，已经不在天线场内）
                    }
                }
                */
                #endregion

                #region 示例在盘存标签事件中操作GPO
                /*
                //设置GPO1为1
                try
                {
                    rdrtmp.GPOSet(1, true);
                }
                catch (System.Exception ex)
                {
                    //操作有可能失败,比如由于断网
                }
                */
                #endregion
                tagList = new List<TagReadData>(tagsArgs.Tags);
                if (!isProcessing)
                {
                    StartProcessing();
                }
            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 读写器异常发生事件的处理函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="expArgs"></param>
        void OnReaderException(object sender, Reader.ReadExceptionEventArgs expArgs)
        {
            Reader rdrtmp = (Reader)sender;
            string aa = rdrtmp.Address + "--异常信息:" + expArgs.ReaderException.ToString();
            //如果需要可在此处记录异常日志
            Debug.WriteLine(aa);

            return;
        }
        public static ushort GetReadPower(int i)
        {
            ushort maxp = Convert.ToUInt16(3300);

            switch (i)
            {
                case 1:
                    maxp = Convert.ToUInt16(GetSetting("Antenna1"));
                    break;
                case 2:
                    maxp = Convert.ToUInt16(GetSetting("Antenna2"));
                    break;
                case 3:
                    maxp = Convert.ToUInt16(GetSetting("Antenna3"));
                    break;
                case 4:
                    maxp = Convert.ToUInt16(GetSetting("Antenna4"));
                    break;
                case 5:
                    maxp = Convert.ToUInt16(GetSetting("Antenna5"));
                    break;
                case 6:
                    maxp = Convert.ToUInt16(GetSetting("Antenna6"));
                    break;
                case 7:
                    maxp = Convert.ToUInt16(GetSetting("Antenna7"));
                    break;
                case 8:
                    maxp = Convert.ToUInt16(GetSetting("Antenna8"));
                    break;
            }

            return maxp;
        }
        public static string GetSetting(string key)
        {
            return ConfigurationManager.AppSettings[key];
        }
        public static void SetSetting(string key, string value)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings[key].Value = value;
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
        /// <summary>
        /// 采集的数据进行上报
        /// </summary>
        public async void submitData()
        {
            StringBuilder strXml = new StringBuilder();
            strXml.Append("<RFIDRequest>").Append("\n");
            strXml.Append("<BindingDeviceID>").Append("12002").Append("</BindingDeviceID>").Append("\n");
            string boxBarCode = "";
            string boxCode = "";
            strXml.Append("<BoxRFID>").Append("\n");
            StringBuilder strXmlBoxCode = new StringBuilder();
            StringBuilder strXmlBoxBarCode = new StringBuilder();
       
            foreach (var item in TagInfos)
            {
                boxCode = boxCode + item.Tag + ",";
                strXmlBoxCode.Append("<BoxCode>").Append(item.Tag).Append("</BoxCode>").Append("\n");
            }
            foreach (var item in GoodsTagInfos)
            {
                boxBarCode = boxBarCode + item.Tag + ",";
                strXmlBoxBarCode.Append("<GoodsCode>").Append(item.Tag).Append("</GoodsCode>").Append("\n");
            }
            strXml.Append(strXmlBoxCode);
            strXml.Append("</BoxRFID>").Append("\n");
            strXml.Append("<GoodsRFID>").Append("\n");
            strXml.Append(strXmlBoxBarCode);
            strXml.Append("</GoodsRFID>").Append("\n");
            strXml.Append("</RFIDRequest>").Append("\n");
            try
            {
                // 设置超时
                this._I_RFID.Endpoint.Binding.SendTimeout = TimeSpan.FromMinutes(5);   // 发送超时 3分钟
                this._I_RFID.Endpoint.Binding.ReceiveTimeout = TimeSpan.FromMinutes(5); // 接收超时 3分钟
                string sResult = await this._I_RFID.RFIDRequestWithReturnAsync(strXml.ToString());
                TxtAdd(sResult);
            }
            catch (Exception ex)
            {
                TxtAdd("请求超时，请手动扫描后重新上传");
            }
            //string sResult = "";
        }
        
        /// <summary>
        /// 子数据发生变化时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TagInfos_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            OnPropertyChanged(nameof(LbTagsCount));
            OnPropertyChanged(nameof(LbGoodsTagsCount));
        }
        #endregion
    }
}
