BoxEquip_ConnectServerTimer.cs 15.2 KB
using Asa;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;

namespace OnlineStore.DeviceLibrary
{
    public partial class BoxEquip
    {
        private System.Timers.Timer serverConnectTimer;
        public void InitConnectServerTimer()
        {
            serverConnectTimer = new System.Timers.Timer();
            serverConnectTimer.Interval = 1000;
            serverConnectTimer.AutoReset = true;
            serverConnectTimer.Enabled = false;
            serverConnectTimer.Elapsed += server_connect_timer_Tick;
        }
        internal void SetConnectServerTimer(bool open)
        {
            serverConnectTimer.Enabled = open;
        }
        #region 与服务器通信定时器

        private string CodeMsg = "";
        private bool isInProcess = false;
        private DateTime lastConTime = DateTime.Now;
        public void server_connect_timer_Tick(object sender, EventArgs e)
        {
            if (isInProcess)
            {
                TimeSpan span = DateTime.Now - lastConTime;
                if (span.TotalSeconds < 60)
                {
                    return;
                }
            }
            isInProcess = true;
            lastConTime = DateTime.Now;
            try
            {
                humBean.HumidityProcess(this);
                //if (IsDebug)
                //{

                //}
                //else
                {
                    if (StoreManager.IsConnectServer)
                    {
                        SendLineStatus();
                    }
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(Name + "定时SendLineStatus出错:" + ex.ToString());
            }
            finally
            {
                isInProcess = false;
            }
        }
        /// <summary>
        /// 获取整个料仓的状态
        /// </summary> 
        public Operation getLineBoxStatus()
        {
            //构建发送给服务器的对象
            Operation lineOperation = new Operation();
            lineOperation.msg = "";
            lineOperation.alarmList = new List<AlarmInfo>();
            lineOperation.cid = CID;
            lineOperation.seq = ConfigAppSettings.nextSeq();
            lineOperation.status = 1;
            if (WarnMsg != "")
            {
                lineOperation.status = (int)DeviceStatus.Warning;
                lineOperation.msg = WarnMsg;
            }
            lineOperation.status = (int)DeviceStatus.StoreOnline;

            BoxStatus boxStatus = new BoxStatus();
            boxStatus.boxId = 1;

            boxStatus.msg = WarnMsg;
            lineOperation.msg = WarnMsg;

            if (WarnMsg.Equals(""))
            {
                boxStatus.msg = CodeMsg;
                lineOperation.msg = CodeMsg;
            }
            CodeMsg = "";
            //WarnMsg = ""; 
            //状态
            boxStatus.status = (int)deviceStatus;
            if (IsDebug)
            {
                boxStatus.status = (int)DeviceStatus.Debugging;
            }
            else if (runStatus.Equals(DeviceStatus.OutStoreBoxEnd) || runStatus.Equals(DeviceStatus.InStoreEnd))
            {
                boxStatus.data.Add(ParamDefine.posId, lastPosId);
                boxStatus.data.Add(ParamDefine.barcode,lastBarcode);
                boxStatus.data.Add(ParamDefine.executeTime, executeTime);
            }
            else if (!lastPosId.Equals(""))
            {
                boxStatus.data.Add(ParamDefine.posId, lastPosId);
                boxStatus.data.Add(ParamDefine.barcode, lastBarcode);
                boxStatus.data.Add(ParamDefine.executeTime,executeTime);
                boxStatus.status = (int)deviceStatus;
                if (lastPosId != "")
                {
                    LogUtil.info("给服务器发送出入库消息:" + Name + ",status【" + deviceStatus + "】posId【" + lastPosId + "】barcode【"+lastBarcode+"】");
                }
                lastPosId = "";
                lastBarcode = "";
            }

            if (MoveInfo.MoveType.Equals(MoveType.InStore)||MoveInfo.MoveType.Equals(MoveType.OutStore))
            {
                if ((MoveInfo.MoveParam != null)&&( MoveInfo.MoveParam.PosInfo!=null))
                {
                    if (!boxStatus.data.ContainsKey(ParamDefine.posId))
                    {
                        boxStatus.data.Add(ParamDefine.posId, MoveInfo.MoveParam.PosInfo.PosId);
                    }
                    boxStatus.data.Add(ParamDefine.code, MoveInfo.MoveParam.PosInfo.barcode);
                }
            }

            //温湿度
            //ASTemperateParam param = HumitureServer.GetTemperateParam(Config.Temperate_Serveraddress);
            HumitureParam param = humBean.LastData;
            if (param != null)
            {
                boxStatus.humidity = param.Humidity.ToString();
                boxStatus.temperature = param.Temperate.ToString();
            }
            lineOperation.boxStatus.Add(1, boxStatus);

            if (!alarmType.Equals(AlarmType.None))
            {
                lineOperation.alarmList.Add(alarmInfo);
            }
            return lineOperation;
        }
        string server = ConfigAppSettings.GetValue(Setting_Init.http_server);
        public void SendLineStatus()
        {
            DateTime time = DateTime.Now;
            //构建发送给服务器的对象
            Operation lineOperation = getLineBoxStatus();
            //如果还没湿度范围,先获取
            if (humBean.NeedGetTem())
            {
                lineOperation.op = 5;
                LogUtil.error(Name + "没有湿度预警范围,需要从服务器获取,发送OP=" + lineOperation.op, DeviceID + 105);
            }
            Operation resultOperation = HttpHelper.PostOperation(SServerManager.GetPostApi(server), lineOperation);
            //LogUtil.info("resultOperation="+ JsonHelper.SerializeObject(resultOperation));
            //发送状态信息到服务器 
            if (resultOperation == null || (resultOperation.op <= 0))
            {
                //判断服务端是否返回出库操作
                return;
            }
            if (resultOperation.op.Equals(1))
            {
                //ReviceInStoreProcess("", resultOperation);
            }
            else if (resultOperation.op.Equals(2))
            {
                ReviceOutStoreProcess(resultOperation);
            }
            else if (resultOperation.op.Equals(5))
            {
                humBean.ProcessHumidityCMD(resultOperation);
            }
            else
            {
                LogUtil.error("收到服务器命令:op=" + resultOperation.op + ",未找到对应处理");
            }
            TimeSpan span = DateTime.Now - time;
            if (span.TotalMilliseconds > 10)
            {
                LogUtil.info(Name + "执行TimerProcess 共处理了【" + span.TotalMilliseconds + "】毫秒");
            }
        }
        public bool ReviceInStoreCMD(string posId, int plateH, int plateW, string message)
        {
            string logName = "入库库位验证【" + message + "】【" + posId + "】:";
            try
            {

                if (runStatus.Equals(RunStatus.Wait))
                {
                    LogUtil.info(logName + " 设备未启动,验证失败");
                    return false;
                }
                //发送扫码内容到服务器进行入库操作
                Operation operation = getLineBoxStatus();
                operation.op = 1;
                operation.data = new Dictionary<string, string>() { { "code", message }, { "boxId", this.DeviceID.ToString() } };
                operation.data.Add("inPos", posId);
                for (int i = 1; i <= 5; i++)
                {
                    bool timeOut = false;
                    Operation resultOperation = HttpHelper.PostOperation(SServerManager.GetPostApi(server), operation);
                    LogUtil.info($"入库验证请求信息【{operation.seq}】【{resultOperation?.seq??-1}】:【{JsonHelper.SerializeObject(operation)}】【{JsonHelper.SerializeObject(resultOperation)}】");
                    if (timeOut)
                    {
                        LogUtil.error(logName + " 第" + i + "次发送超时 ");
                        continue;
                    }
                    if (resultOperation == null)
                    {
                        // CodeMsg = "二维码【" + message + "】没有收到服务器反馈";
                        LogUtil.error(logName + " 没有收到服务器反馈 ");
                    }
                    else if (!string.IsNullOrEmpty(resultOperation.msg))
                    {
                        //如果有提示消息,直接显示提示
                        LogUtil.error(logName + "服务器反馈 :" + resultOperation.msg);
                        continue;
                    }
                    else if (resultOperation.op.Equals(1)&& resultOperation.seq.Equals(operation.seq))
                    {
                        LogUtil.info(logName + " 成功"+$"【{JsonHelper.SerializeObject(resultOperation.data)}】");
                        return true;
                    }
                    else
                    {
                        LogUtil.info(logName + "服务器反馈 :" + JsonHelper.SerializeObject(resultOperation));
                        continue;
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(logName + " 出错:" + ex.ToString());

            }
            return false;
        }
        //public string LastVisualRfid = "";
        private void ReviceOutStoreProcess(Operation resultOperation)
        {
            DateTime time = DateTime.Now;
            Dictionary<string, string> data = resultOperation.data;
            if (data != null && data.ContainsKey(ParamDefine.posId)
                      && data.ContainsKey(ParamDefine.plateH) && data.ContainsKey(ParamDefine.plateW))
            {
                char splitChar = '|';
                string[] posIdArray = data[ParamDefine.posId].Split(splitChar);
                string[] plateWArray = data[ParamDefine.plateW].Split(splitChar);
                string[] plateHArray = data[ParamDefine.plateH].Split(splitChar);
                //if (string.IsNullOrEmpty(StoreManager.LastVisualRfid))
                //{
                //    StoreManager.LastVisualRfid = data[ParamDefine.rfid];
                //}
                //else if (StoreManager.LastVisualRfid != data[ParamDefine.rfid])
                //{
                //    LogUtil.error(Name + $" 上一个工单还未结束LastVisualRfid={StoreManager.LastVisualRfid}, CurrentVisualRfid={data[ParamDefine.rfid]}");
                //    return;
                //}
                bool urgentReel = FormUtil.GetBoolData(data, ParamDefine.urgentReel);
                //bool cutReel = FormUtil.GetBoolData(data, ParamDefine.cutReel);
                //bool smallReel = FormUtil.GetBoolData(data, ParamDefine.smallReel);
                //string rfid = data.ContainsKey(ParamDefine.rfid) ? data[ParamDefine.rfid] : "";
                //int rfidLoc = FormUtil.GetIntData(data, ParamDefine.rfidLoc);
                string barcode = data.ContainsKey(ParamDefine.barcode) ? data[ParamDefine.barcode] : "";
                //string realRfid = data.ContainsKey(ParamDefine.realRfid) ? data[ParamDefine.realRfid] : "";
                //int taskCount = FormUtil.GetIntData(data, ParamDefine.taskCount, 0);

                //urgentReel: true 表示紧急料,需要出到料串上
                //cutReel: true 表示分盘料,需要出到料串上
                //smallReel: true  小料(7x8),放置到小料架上
                //rfid: 分配的料架RFID
                //rfidLoc: 料架的架位,值为 - 1时,可以自由分配皮带线, 小料时,架位为1 - 46优先走1 / 2号皮带线,47 - 92优先走3 / 4号皮带线, 70,71,72时只能分配到3 / 4号皮带线; 大料时,架位1 - 6优先走1 / 2号皮带线, 7 - 12优先走3 / 4号皮带线

                string dataStr = JsonHelper.SerializeObject(data);
                LogUtil.info("收到服务器出库消息:【" + dataStr + "】");

                int index = -1;
                foreach (string posId in posIdArray)
                {
                    index++;
                    int plateW = Convert.ToInt32(plateWArray[index]);
                    int plateH = Convert.ToInt32(plateHArray[index]);

                    InOutParam inoutParam = new InOutParam(new InOutPosInfo(barcode, posId, plateW, plateH, urgentReel));
                    //根据发送的posId获取位置列表
                    BoxPosition position = CSVPositionReader<BoxPosition>.GetPositon(posId);
                    if (position == null)
                    {
                        //出入库没有找到服务器发送的库位,需要打印日志方便查询原因
                        WarnMsg = Name + "未找到库位:【" + inoutParam.PosInfo.ToStr() + "】";
                        LogUtil.error(WarnMsg);
                        continue;
                    }
                    try
                    {
                        //判断是否接收过此库位的出库信息
                        if (MoveInfo.MoveType.Equals(MoveType.OutStore) && (MoveInfo.MoveParam.PosInfo.PosId.Equals(posId)|| 
                            (MoveInfo.MoveParam.PosInfoBack !=null && MoveInfo.MoveParam.PosInfoBack.PosId.Equals(posId))))
                        {
                            LogUtil.error(Name + " 出库命令【" + inoutParam.PosInfo.ToStr() + "】重复,正在【" + posId + "】出库中");
                            continue;
                        }

                        //判断排队列表中是否已存在
                        List<InOutParam> reviceList = new List<InOutParam>();
                        reviceList.AddRange(waitAOutStoreList);
                        reviceList.AddRange(waitBOutStoreList);
                        reviceList = (from m in reviceList where m.PosInfo.PosId.Equals(posId) select m).ToList<InOutParam>();
                        if (reviceList.Count > 0)
                        {
                           // LogUtil.error(Name + " 出库命令【" + inoutParam.PosInfo.ToStr() + "】重复,排队列表中已存在【" + reviceList[0].PosInfo.ToStr() + "】");
                            continue;
                        }

                    }
                    catch (Exception ex)
                    {
                        LogUtil.error(Name + "验证出库【" + inoutParam.PosInfo.ToStr() + "】是否重复出错:" + ex.ToString());
                    }
                    StartExecuctOut(inoutParam);
                }

                TimeSpan span = DateTime.Now - time;
                if (span.TotalMilliseconds > 10)
                {
                    LogInfo(Name + "执行 ReviceOutStoreProcess 共处理了【" + span.TotalMilliseconds + "】毫秒");
                }
            }
        }
        #endregion

    }
}