Exemple #1
0
        /// <summary>
        /// 根据指令创建指定数据项对象(代码未完成)
        /// </summary>
        /// <returns></returns>
        public DataItem getDataItem(byte ser)
        {
            byte[] cmdData = strToToHexByte(_cmd.DataCommand);
            //重新编写指令序列号
            cmdData[2] = ser;

            if (_cmd.Identification == "A013" && _cmd.ControlCode == 0x04)
            {
                cmdData[3] = ser;
            }

            DataItem item = null;

            switch ((ControlCode)_cmd.ControlCode)
            {
            case ControlCode.ReadData:
                //读数据指令
                item = new DataItem_ReadData_ASK(cmdData);
                break;

            case ControlCode.WriteData:
                //写数据
                item = getWriteDataAskItem(cmdData);
                break;

            case ControlCode.ReadKeyVersion:
                //读Key版本号
                break;

            case ControlCode.ReadMeterAdress:
                //读地址
                break;

            case ControlCode.WriteMeterAdress:
                //写地址
                break;

            case ControlCode.WriteMeterNum:
                //写表底
                break;

            case ControlCode.CYReadData:
                //读参数
                item = getCYReadDataAskItem(cmdData);
                break;

            case ControlCode.CYWriteData:
                //创源内部写指令(参数设置)
                item = getCYWriteDataAskItem(cmdData);
                break;

            case ControlCode.CTR_6:    //主动上报数据中
                item = new DataItem_C001(cmdData);
                break;

            default:
                break;
            }
            return(item);
        }
Exemple #2
0
        private bool ReportToZhuZhan(Stopwatch watch, Socket socket)
        {
            watch.Start();
            DataItem_C001 item_C001 = new DataItem_C001(ser++, DateTime.Now, this.TotalAmount, this.TotalTopUp - this.CurrentBalance, this.CurrentBalance, this.LastTotal, this._st1, this._st2);
            TaskArge      taskArge  = new TaskArge(this.Mac, item_C001, ControlCode.CTR_6, MKey);
            Frame         frame     = new Frame(taskArge);
            int           iTime     = 1;

            byte[] buffer = frame.GetBytes();
            while (socket.Poll(100, SelectMode.SelectWrite))
            {
                socket.Send(buffer);
                break;
            }
            Notice(string.Format("{1:yyyy-MM-dd HH:mm:ss} 第{0}次发送上报数据请求帧\r", iTime, DateTime.Now));

            string message;

            //等待应答
            while (true)
            {
                Thread.Sleep(100);
                if (socket.Poll(10, SelectMode.SelectRead))
                {
                    int dLength = socket.Available;
                    Thread.Sleep(100);
                    if (dLength != socket.Available)
                    {
                        dLength = socket.Available;
                    }
                    buffer = new byte[dLength];
                    socket.Receive(buffer);
                    Notice(string.Format("{1:yyyy-MM-dd HH:mm:ss}接收到主站应答数据:{0}\r", MyDataConvert.BytesToHexStr(buffer), DateTime.Now));

                    taskArge = JieXi(buffer, out message);
                    if (taskArge != null && taskArge.ControlCode == ControlCode.CTR_7)
                    {
                        Notice(string.Format("第{0}次发送上报数据请求完成。\r", iTime));
                    }
                    Notice(string.Format("本次上报数据总用时:{0}毫秒\r", watch.ElapsedMilliseconds));
                    this._reportWatch.Restart();
                    break;
                }
                else if (socket.Poll(100, SelectMode.SelectError))
                {
                }
                if (watch.ElapsedMilliseconds >= 1000 * 10)
                {
                    if (iTime >= 3)
                    {
                        //接收不到主站应答,本次上报结束
                        this.tcpClient.Close();
                        this.tcpClient = null;
                        return(false);
                    }
                    iTime++;
                    buffer = frame.GetBytes();
                    socket.Send(buffer);
                    Notice(string.Format("{1:yyyy-MM-dd HH:mm:ss}接收到主站应答数据:{0}\r", MyDataConvert.BytesToHexStr(buffer), DateTime.Now));
                    watch.Restart();
                }
            }

            return(true);
        }
Exemple #3
0
        //Semaphore _semaphore = new Semaphore(10, 10);

        /// <summary>
        /// 上报数据并接收主站指令
        /// </summary>
        private void ReportData()
        {
            //FE FE 68 30 39 61 51 23 35 51 04 21 1E C0 01 20 40 14 16 22 04 15 20 18 56 42 37 18 56 02 00 18 56 02 00 18 56 02 00 23 00 00 00 6F 16
            DataItem_C001 item_C001 = new DataItem_C001(ser++, DateTime.Now, this.TotalAmount, LJMoney, CurrentBalance, this.LastTotal, _st1, _st2);
            TaskArge      taskArge  = new TaskArge(this.Mac, item_C001, ControlCode.CTR_6, MKey);
            //连接服务器
            Stopwatch watch = new Stopwatch();

            watch.Start();
            byte[] buffer = null;
            try
            {
                this.tcpClient = new System.Net.Sockets.TcpClient();
                this.tcpClient.Connect(this.hostname, this.port);
                Socket socket = tcpClient.Client;
                Notice(string.Format("{0} 表连接服务器完成.\r", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));

                if (!ReportToZhuZhan(watch, socket))
                {
                    return;
                }

                Frame  frame = new Frame(taskArge);
                string message;

                //等待主站指令
                Notice(string.Format("================================\r"));

                watch.Restart();
                while (true)
                {
                    if (watch.ElapsedMilliseconds >= 1000 * 20)
                    {
                        //20秒内没有收到任何主站指令,关闭连接并结束本次通信
                        this.tcpClient.Close();
                        Notice(string.Format("{0} 关闭表连接\r\n--------------------------------\r", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                        this._reportWatch.Restart();
                        break;
                    }
                    //if (this._reportWatch.ElapsedMilliseconds >= this.周期 * 60 * 1000)
                    //{
                    //    //上报数据周期到
                    //    watch.Restart();
                    //    if (!ReportToZhuZhan(watch,socket))
                    //    {
                    //        return;
                    //    }
                    //}
                    //检查数据
                    if (socket.Poll(10, SelectMode.SelectRead))
                    {
                        int dLength = socket.Available;
                        Thread.Sleep(100);
                        if (dLength != socket.Available)
                        {
                            dLength = socket.Available;
                        }
                        buffer = new byte[dLength];
                        socket.Receive(buffer);
                        Notice(string.Format("{1:yyyy-MM-dd HH:mm:ss} 接收到主站数据:{0}\r", MyDataConvert.BytesToHexStr(buffer), DateTime.Now));
                        Thread.Sleep(10);
                        // _semaphore.WaitOne();
                        //解析接收到的数据
                        try
                        {
                            taskArge = JieXi(buffer, out message);
                            //  _semaphore.Release();
                            Notice(string.Format("控制码:{0} 指令:{1}\r", taskArge.ControlCode, taskArge.Data.IdentityCode));
                        }
                        catch (Exception ex)
                        {
                            // _semaphore.Release();
                            throw ex;
                        }

                        if (taskArge != null && (((byte)taskArge.ControlCode) & 0x80) == 0x00)
                        {
                            //接收到主站请求数据
                            taskArge = CreateAnswerData(taskArge);
                            frame    = new Frame(taskArge);
                            buffer   = frame.GetBytes();
                            socket.Send(buffer);
                            Notice(string.Format("{0:yyyy-MM-dd HH:mm:ss}从站应答完成。\r", DateTime.Now));
                            watch.Restart();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Notice(string.Format("{1:yyyy-MM-dd HH:mm:ss} 程序异常:{0}\r", e.Message, DateTime.Now));

                Debug.Print(e.Message);
            }
        }
Exemple #4
0
        private bool _lastDowith = false;      //上一条上报数据是否处理完成,已处理完成则丢弃
        /// <summary>
        /// 处理主动上报数据
        /// </summary>
        /// <param name="control"></param>
        /// <param name="data"></param>
        public void ReportData(string mac, byte control, byte[] data, IotProtocolType protocolType)
        {
            lock (this._meterLink)
            {
                this._reportWatch.Restart();
                CY.IoTM.Protocol.Frame frame = null;
                if (protocolType == IotProtocolType.RanQiBiao)
                {
                    //燃气表协议
                    //解密数据
                    byte[]        desData   = Encryption.Decry(data, MKey);
                    DataItem_C001 item_C001 = new DataItem_C001(desData);
                    if (this._lastReportData == null || this._lastReportData.ReadDate != item_C001.ReadDate)
                    {
                        this._lastReportData = item_C001;
                        _lastDowith          = false;
                    }
                    //else if (_lastDowith)
                    //{
                    //    //上报的数据重复,并上条记录已处理过
                    //    return;
                    //}

                    //解析并应答
                    DataItem_C001_Answer itemAnswer = new DataItem_C001_Answer(item_C001.SER);
                    TaskArge             taskArge   = new TaskArge(mac, itemAnswer, ControlCode.CTR_7, MKey);
                    frame = new Protocol.Frame(taskArge);
                    if (this._reportWatch.ElapsedMilliseconds < Answer_YanShi)
                    {
                        Thread.Sleep(Answer_YanShi - (int)this._reportWatch.ElapsedMilliseconds);
                    }
                    this._meterLink.Send(frame.GetBytes());//应答数据
                    //检查上线的表是否登记到系统中
                    if (this.meter == null)
                    {
                        Log.getInstance().Write(MsgType.Information, "表:" + mac + " 在系统中未登记。");
                        Log.getInstance().Write(new OneMeterDataLogMsg(mac, "表:" + mac + "  在系统中未登记。"));
                        return;
                    }
                    Thread.Sleep(300);

                    //将接收到抄表数据提交给数据中心处理
                    Stopwatch _watch = new Stopwatch();
                    _watch.Start();
                    ReportData(item_C001);
                    //new Thread(new ParameterizedThreadStart(ReportData)).Start(item_C001);
                    Console.WriteLine("处理表:{0} 上报数据总用时:{1} 毫秒", mac, _watch.ElapsedMilliseconds);

                    //Log.getInstance().Write(MsgType.Information, "处理表:" + this.MAC + " 上报数据总用时:" + _watch.ElapsedMilliseconds + " 毫秒");
                    //Log.getInstance().Write(new OneMeterDataLogMsg(this.MAC, "处理表:" + this.MAC + " 上报数据总用时:" + _watch.ElapsedMilliseconds + " 毫秒" + "; 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
                    _lastDowith = true;
                    //_watch.Stop();
                }
                else if (protocolType == IotProtocolType.LCD)
                {
                    //LCD屏协议
                    if (data[0] == 0xc0 && data[1] == 0x02)
                    {
                        //下载
                        DataItem_C002 item_C002 = new DataItem_C002(data);
                        Log.getInstance().Write(new OneMeterDataLogMsg(mac, $"[{this._meterLink.socketHandle}]接收到LCD下载请求,文件名:{item_C002.FileName} 文件长度:{item_C002.FileLength} 请求段号:{item_C002.CurrentSegmentsIndex}"));

                        MemoryStream stream = new MemoryStream();
                        string       str    = ADFileCacheService.getInstance().ReadFileSeg(stream, item_C002.FileName.Substring(0, 4), item_C002.FileName, item_C002.FileLength, item_C002.TotalSegments, item_C002.CurrentSegmentsIndex, item_C002.DataLength);


                        DataItem answerItem = null;
                        TaskArge answerArge = null;
                        if (str != "")
                        {
                            //没有读取到要下载的文件,返回异常应答信息
                            answerItem = new DataItem_C002_Answer_Err(item_C002.SER);
                            answerArge = new TaskArge(mac, answerItem, ControlCode.CTR_8);
                            //TODO:记录异常应答记录
                        }
                        else
                        {
                            byte[] tmp = new byte[stream.Length];
                            stream.Position = 0;
                            stream.Read(tmp, 0, tmp.Length);
                            answerItem = new DataItem_C002_Answer(item_C002.SER, item_C002.FileName, item_C002.FileLength, item_C002.TotalSegments, item_C002.CurrentSegmentsIndex, tmp);
                            answerArge = new TaskArge(mac, answerItem, ControlCode.CTR_7, IotProtocolType.LCD);
                        }
                        //发送应答数据
                        frame = new Protocol.Frame(answerArge);
                        //if (this._reportWatch.ElapsedMilliseconds < Answer_YanShi)
                        //    Thread.Sleep(Answer_YanShi - (int)this._reportWatch.ElapsedMilliseconds);

                        this._meterLink.Send(frame.GetBytes());//应答数据
                        if (this.meter == null)
                        {
                            Log.getInstance().Write(MsgType.Information, "表:" + mac + " 在系统中未登记。");
                            Log.getInstance().Write(new OneMeterDataLogMsg(mac, "表:" + mac + "  在系统中未登记。"));
                            return;
                        }
                    }
                    else
                    {
                        Log.getInstance().Write(new OneMeterDataLogMsg(mac, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}接收到错误的请求指令:{data[0]} {data[1]} "));
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// 上报数据线程
        /// </summary>
        private void ReportData(object ParObject)
        {
            //*********该函数要求2秒内必须返回*****************//
            DataItem_C001 item_C001 = ParObject as  DataItem_C001;

            if (item_C001 == null || this.meter == null)
            {
                return;
            }
            //编写调用上报数据中心抄表数据处理程序
            //Console.WriteLine(string.Format("于:{1} 接收到表{0}上报的数据:累计气量={2},累计金额={3},剩余金额={4},上次结算累计量={5}", this.meter.Mac,DateTime .Now,
            //    item_C001.LJGas,item_C001.LJMoney,item_C001.SYMoney,item_C001.LastLJGas));
            Log.getInstance().Write(string.Format("于:{1} 接收到表{0}上报的数据:累计气量={2},累计金额={3},剩余金额={4},上次结算累计量={5}", this.meter.Mac, DateTime.Now,
                                                  item_C001.LJGas, item_C001.LJMoney, item_C001.SYMoney, item_C001.LastLJGas), MsgType.Information);
            //Log.getInstance().Write(new OneMeterDataLogMsg(this.meter.Mac, string.Format("接收到表{0}上报的数据:累计气量={2},累计金额={3},剩余金额={4},上次结算累计量={5}; 时间:{1} ", this.meter.Mac, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
            //    item_C001.LJGas, item_C001.LJMoney, item_C001.SYMoney, item_C001.LastLJGas)));

            //WCFServiceProxy<IReportData> _iReportDataProxy = new WCFServiceProxy<IReportData>();
            this.meter             = this.tms.GetMeter(meter.Mac);
            this.meter.TotalAmount = item_C001.LJGas;

            if (!meter.IsDianHuo && meter.LastGasPoint > item_C001.LJGas && meter.TotalTopUp == 0)
            {
                //this.meter.LastGasPoint = item_C001.LJGas;
            }

            CY.IoTM.DataService.Business.ReportDataService rds = new DataService.Business.ReportDataService();
            //SubmitResult result = _iReportDataProxy.getChannel
            SubmitResult result = rds.Submit(this.meter,
                                             new SubmitData()
            {
                JSDay     = item_C001.JSDay,
                LastLJGas = item_C001.LastLJGas,
                LJGas     = item_C001.LJGas,
                LJMoney   = item_C001.LJMoney,
                ReadDate  = item_C001.ReadDate,
                ST1       = item_C001.ST1,
                ST2       = item_C001.ST2,
                SYMoney   = item_C001.SYMoney
            });


            // _iReportDataProxy.CloseChannel();
            //判断是否需要重新加载Meter对象
            if (result.IsReLoadMeter)//上报数据后,后台已更新Meter对象数据,当前meter对象已过失,需要重新加载。
            {
                //WCFServiceProxy<ITaskManage> _iTaskManageProxy = new WCFServiceProxy<ITaskManage>();
                try
                {
                    //Meter _m = _iTaskManageProxy.getChannel.GetMeter(meter.Mac);
                    Meter _m = this.tms.GetMeter(meter.Mac);
                    //_iTaskManageProxy.CloseChannel();
                    this.meter = _m;
                }
                catch (Exception er)
                {
                    Log.getInstance().Write(MsgType.Error, "重新加载表:" + meter.Mac + " 信息失败,原因:" + er.Message);
                    Log.getInstance().Write(new OneMeterDataLogMsg(meter.Mac, "重新加载表:" + meter.Mac + " 信息失败,原因:" + er.Message));
                }
            }
            if (result.IsCalibration && result.Calibrations != null)
            {
                //执行校准
                //
                this._xZTaskList = result.Calibrations;
            }
        }