StoreManager.cs 17.2 KB
using log4net;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text; 
using System.Windows.Forms;

namespace OnlineStore.DeviceLibrary
{
    public class StoreManager
    {
        /// <summary>
        /// 当前出入库的模式
        /// </summary>
        public static int CurrInOutType = 0;

        public static readonly ILog LOGGER = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public static PackingStoreBean Store = null;
        public static Store_Config Config = null;
        public static Dictionary<int, BaseConfig> AllConfigMap = null;
        private static bool isInit = false;
        public static bool IsConnectServer = !ConfigAppSettings.GetValue(Setting_Init.http_server).Equals("");
        public StoreManager()
        {
        }

        #region 配置文件加载更新
        public static void CheckEnum(Type type)
        {
            if (type.IsEnum)
            {
                List<int> valueList = new List<int>();
                foreach (int item in Enum.GetValues(type))
                {
                    if (valueList.Contains(item))
                    {
                        LogUtil.error(type.Name + "枚举值:" + item + "重复存在,请检查代码,即将 退出程序!");
                        MessageBox.Show(type.Name + "枚举值:" + item + "重复存在,请检查代码,即将 退出程序!");
                        Application.Exit();
                        break;
                    }
                    valueList.Add(item);
                }
            }
        }
        public static PackingStoreBean InitStore()
        {
            try
            {
                AllConfigMap = new Dictionary<int, BaseConfig>();
                BaseConfig.ProIOIpMap = new Dictionary<string, string>();
                if (!isInit)
                {
                    string server = ConfigAppSettings.GetValue(Setting_Init.http_server);
                    if (server.Equals(""))
                    {
                        IsConnectServer = false;
                    }
                    else
                    {
                        //IsConnectServer = true;
                    }
                    CheckEnum(typeof(StoreMoveStep));
                    CheckEnum(typeof(StoreStatus));
                    CheckEnum(typeof(StoreRunStatus));

                    isInit = true;
                    string storeType = ConfigAppSettings.GetValue(Setting_Init.Store_Type);
                    int count = ConfigAppSettings.GetIntValue(Setting_Init.store_count);
                    LogUtil.info(LOGGER, "配置的料仓 类型=" + storeType + ",开始加载料仓配置");
                    string appPath = Application.StartupPath;
                    string CID = ConfigAppSettings.GetValue(Setting_Init.Store_CID);
                    Dictionary<int, AC_BOX_Config> storeConfig = new Dictionary<int, AC_BOX_Config>();
                    if (storeType == StoreType.RC_AC_PA)
                    {

                        string linefilePath = appPath + ConfigAppSettings.GetValue(Setting_Init.Store_ConfigPath);
                        Config = CSVConfigReader.LoadLineConfig(0, CID, "Line", linefilePath);
                        AllConfigMap.Add(0, Config);

                        string moveEquipConfig = ConfigAppSettings.GetValue(Setting_Init.BOX_ConfigPath);
                        for (int i = 1; i <= count; i++)
                        {
                            string nameStr = i.ToString().PadLeft(1, '0');
                            string config = appPath + moveEquipConfig.Replace(".csv", "_" + nameStr + ".csv");
                            string storeIdConfig = Setting_Init.Store_CID + "_" + i;
                            string boxCid = ConfigAppSettings.GetValue(storeIdConfig);
                            AC_BOX_Config moveConfig = CSVConfigReader.LoadBoxConfig(i, boxCid, "BOX", config);
                            AllConfigMap.Add(i, moveConfig);
                            storeConfig.Add(i, moveConfig);
                        }
                        string positionConfigFile = appPath + ConfigAppSettings.GetValue(Setting_Init.Store_Position_Config);
                        if (count > 1 || (!File.Exists(positionConfigFile)))
                        {
                            for (int i = 1; i <= count; i++)
                            {
                                string nameStr = i.ToString().PadLeft(1, '0');
                                string fileN = positionConfigFile.Replace(".csv", "_" + nameStr + ".csv");
                                CSVPositionReader<ACBoxPosition>.AddCSVFile(fileN, i);
                            }
                        }
                        else
                        {
                            CSVPositionReader<ACBoxPosition>.AddCSVFile(positionConfigFile);
                        }
                        LogUtil.info(LOGGER, "加载料仓完成!");

                    }

                    string shelfConfig = appPath + ConfigAppSettings.GetValue(Setting_Init.Shelf_Position_Config);
                    //if (File.Exists(shelfConfig))
                    //{
                    //    CSVPositionReader<ShelfPosition>.AddCSVFile(shelfConfig);
                    //}
                    if (count > 1 || (!File.Exists(shelfConfig)))
                    {
                        for (int i = 1; i <= count; i++)
                        {
                            string nameStr = i.ToString().PadLeft(1, '0');
                            string fileN = shelfConfig.Replace(".csv", "_" + nameStr + ".csv");
                            CSVPositionReader<ShelfPosition>.AddCSVFile(fileN, i);
                        }
                    }
                    else
                    {
                        CSVPositionReader<ShelfPosition>.AddCSVFile(shelfConfig);
                    }
                    Store = new PackingStoreBean(Config, storeConfig);
                }
            }
            catch (Exception ex)
            {
                LOGGER.Error("出错:", ex);
                MessageBox.Show(ex.ToString(), "加载配置错误(请检查配置)");
                Application.Exit();
            }
            return Store;
        }
        /// <summary>
        /// 修改了料仓配置,更新缓存,更新配置文件(只能更新PRO的配置)
        /// </summary>
        /// <param name="kTK_LA_Store_Config"></param>
        public static bool UpdateBoxConfig(AC_BOX_Config storeConfig)
        {
            try
            {
                //位置配置到文件中
                string appPath = Application.StartupPath;
                string configFile = appPath + ConfigAppSettings.GetValue(Setting_Init.BOX_ConfigPath);
                if (!Directory.Exists(configFile))
                {

                    configFile = configFile.Replace(".csv", "_" + storeConfig.DeviceID + ".csv");
                }
                bool result = CSVConfigReader.SaveBoxPosition(configFile, storeConfig);

                if (!result)
                {
                    LOGGER.Error("保存配置文件失败:" + configFile);
                }
                AllConfigMap[storeConfig.DeviceID] = storeConfig;
                Store.BoxConfigMap[storeConfig.DeviceID] = storeConfig;
                Store.BoxMap[storeConfig.DeviceID].Config = storeConfig;
                Store.BoxMap[storeConfig.DeviceID].MoveAxisConfig();
                return true;
            }
            catch (Exception ex)
            {
                LOGGER.Error("出错:", ex);
            }
            return false;
        }

        #endregion

        #region 位置加载

        public static bool LoadInoutParam(InOutParam param, bool needCheckShelf, AC_BOX_Bean box)
        {
            if (param == null)
            {
                return false;
            }
            //加载位置
            if (param.MoveP == null)
            {
                LineMoveP p = new LineMoveP();
                ACBoxPosition position = CSVPositionReader<ACBoxPosition>.GetPositon(param.PosID);
                if (position == null)
                {
                    LogUtil.error(box.Name + "GetPositon[" + param.PosID + "]=null,没有库位不能执行出入库");
                    return false;
                }
                ShelfPosition sp = CSVPositionReader<ShelfPosition>.GetPositon(param.ShelfPosID);
                if (sp == null && needCheckShelf)
                {
                    LogUtil.error(box.Name + "GetPositon[" + param.ShelfPosID + "]=null,没有库位不能执行出入库");
                    return false;
                }
                if (sp != null)
                {
                    p.InOut_P101 = sp.InoutAxis_P101;
                    p.UpDown_LP101 = sp.UpDownAxis_LP101;
                    p.UpDown_HP102 = sp.UpDownAxis_HP102;
                    p.Middle_P101 = sp.MiddleAxis_P101;
                }

                p.ComPress_P1 = box.Config.CompAxis_P1_Position;
                p.InOut_P1 = box.Config.InOutAxis_P1_Position;
                p.Middle_P1 = box.Config.MiddleAxis_P1;

                p.InOut_P2 = box.Config.InOutAxis_P2_Position;
                p.UpDown_P1 = box.Config.UpDownAxis_P1;
                //   p.UpDown_P8 = box.Config.UpDownAxis_DoorIBPosition_P8;
                p.UpDown_P2 = box.Config.UpDownAxis_P2;
                //   p.UpDown_P7 = box.Config.UpDownAxis_DoorOBPosition_P7;

                p.InOut_P11 = box.Config.InOutAxis_P11_Position;
                p.Middle_P11 = box.Config.MiddleAxis_P11;
                p.UpDown_P11 = box.Config.UpDownAxis_P11;
                p.UpDown_P12 = box.Config.UpDownAxis_P12;

                p.ComPress_P2 = box.Config.GetComP2(position.BagHigh).TargetComP2();
                p.ComPress_P3 = p.ComPress_P2 + box.Config.CompAxis_P3_P2_Value;
                p.InOut_P3 = position.InoutAxis_P3;
                p.Middle_P2 = position.MiddleAxis_P2;
                p.UpDown_P3 = position.UpdownAxis_IH_P3;
                p.UpDown_P4 = position.UpdownAxis_IL_P4;
                p.UpDown_P5 = position.UpdownAxis_OH_P5;
                p.UpDown_P6 = position.UpdownAxis_OL_P6;
                param.MoveP = p;

                if (String.IsNullOrEmpty(param.PlateH))
                {
                    param.PlateH = position.BagHigh.ToString();
                }
                if (string.IsNullOrEmpty(param.PlateW))
                {
                    param.PlateW = position.BagWidth.ToString();
                }
                return true;
            }
            return true;
        }

        #endregion


        private static string api_communication = "service/store/communication";    //流水线状态通信接口 
        public static string GetPostApi(string host)
        {
            if (host == "")
            {
                host = ConfigAppSettings.GetValue(Setting_Init.http_server);
            }
            if (!host.StartsWith("http://"))
            {
                host = "http://" + host;
            }
            if (!host.EndsWith("/"))
            {
                host = host + "/";
            }
            return host + api_communication;
        }
        private static string GetAddr(string addr, Dictionary<string, string> paramsMap)
        {
            string server = ConfigAppSettings.GetValue(Setting_Init.http_server);
            if (server.EndsWith("/"))
            {
                server = server.Substring(0, server.Length - 1);
            }
            string path = server + addr.Trim() + "?";
            foreach (string paramName in paramsMap.Keys)
            {
                string par = System.Web.HttpUtility.UrlEncode(paramsMap[paramName], System.Text.Encoding.UTF8);
                path += paramName + "=" + par + "&";
            }
            path = path.Substring(0, path.Length - 1);
            return path;
        }
        /// <summary>
        /// 3  放入料架(A,B,C,D)后调用,根据返回值决定当前料架是否放满,以及后续是否还有任务
        //        地址: /rest/api/qisda/device/putShelfFinished
        /// </summary>
        private static string Addr_putShelfFinished = "/rest/api/qisda/device/putShelfFinished";
        public static string PutShelfFinished(string deviceName, string barcode, string rfid, string rfidPosId, out ShelfData shelfData)
        {
            string msg = "";
            shelfData = null;
            try
            {
                Dictionary<string, string> paramMap = new Dictionary<string, string>();
                paramMap.Add("barcode", barcode);      // 参数: barcode=料盘的条码
                paramMap.Add("rfid", rfid);                     // rfid = 料架的RFID信息
                paramMap.Add("rfidLoc", rfidPosId);     // rfidLoc=料架的架位信息 
                // paramMap.Add("robotIndex", "0");          // robotIndex = 机器人编号(非机器人放置时不传此参数), IP为51的机器人为1, 52的机器人为2, 53的机器人为3
                string server = GetAddr(Addr_putShelfFinished, paramMap);
                string resultStr = HttpHelper.Post(server, "");
                LogUtil.info("PutShelfFinished  【" + server + "】【" + resultStr + "】");
                // 返回: {"code": 0, "msg":"ok", "data":{"rfid":"xxx","smallEmpty":0,"bigEmpty":0, "packageEmpty":0,"cutPackageTask":0,"packageTask":10,"cutTask":10, "smallTask":5, "bigTask":5}
                ServerData serverResult = JsonHelper.DeserializeJsonToObject<ServerData>(resultStr);
                if (serverResult == null)
                {
                    return msg = deviceName + "PutShelfFinished【 " + barcode + "】【" + rfid + "】【" + rfidPosId + "】没有收到服务器反馈";
                }
                else if (serverResult.code.Equals(0).Equals(false))
                {
                    return msg = deviceName + " PutShelfFinished【 " + barcode + "】【" + rfid + "】【" + rfidPosId + "】  :" + serverResult.msg;
                }
                if (String.IsNullOrEmpty(serverResult.data).Equals(false))
                {
                    shelfData = JsonHelper.DeserializeJsonToObject<ShelfData>(serverResult.data);
                }
            }
            catch (Exception ex)
            {
                LogUtil.error(deviceName + " " + ex.ToString());
            }
            return "";
        }
    } 
    public class ServerData
    {
        //{"code":0,"msg":"ok","data":"7"}
        //返回: {"code": 0, "msg":"ok", "data":{"rfid":"xxx","smallEmpty":0,"bigEmpty":0, "packageEmpty":0,"cutPackageTask":0,"packageTask":10,"cutTask":10, "smallTask":5, "bigTask":5}
        public int code { get; set; }

        public string msg { get; set; }

        public string data { get; set; }
    }

    public class ShelfData
    {
        /// <summary>
        /// rfid: 当前料架的RFID
        /// </summary>
        public string rfid { get; set; }
        /// <summary>
        /// packageEmpty: 当前料架还可放置的包装料的数量(C料架和A料架有值, 其他料架为0)
        /// </summary>
        public int packageEmpty { get; set; }
        /// <summary>
        /// smallEmpty: 当前料架还可放置的小料盘(7x8)的数量(D料架, 其他料架为0)
        /// </summary>
        public int smallEmpty { get; set; }
        /// <summary>
        /// bigEmpty:当前料架还可放置的大料盘的数量(C料架, 其他料架为0)
        /// </summary>
        public int bigEmpty { get; set; }
        /// <summary>
        /// cutPackageTask:还有多少盘分盘的包装料任务(放到A料架上, 转运到分盘区)
        /// </summary>
        public int cutPackageTask { get; set; }
        /// <summary>
        /// packageTask:还有多少盘包装料任务(放到A料架上, 并转运到包装线, 最终到C料架)
        /// </summary>
        public int packageTask { get; set; }
        /// <summary>
        /// cutTask: 还有多少盘分盘料任务(放置到料串B上, 转运到分盘区)
        /// </summary>
        public int cutTask { get; set; }
        /// <summary>
        /// smallTask: 还有多少盘小料任务(放置到双层线的D料架上)
        /// </summary>
        public int smallTask { get; set; }
        /// <summary>
        /// bigTask: 还有多少盘大料任务(放置到C料架上)
        /// </summary>
        public int bigTask { get; set; }

        //         rfid: 当前料架的RFID
        //         packageEmpty: 当前料架还可放置的包装料的数量(C料架和A料架有值, 其他料架为0)
        //         smallEmpty: 当前料架还可放置的小料盘(7x8)的数量(D料架, 其他料架为0)
        //         bigEmpty:当前料架还可放置的大料盘的数量(C料架, 其他料架为0)
        //         cutPackageTask:还有多少盘分盘的包装料任务(放到A料架上, 转运到分盘区)
        //         packageTask:还有多少盘包装料任务(放到A料架上, 并转运到包装线, 最终到C料架)
        //         cutTask: 还有多少盘分盘料任务(放置到料串B上, 转运到分盘区)
        //         smallTask: 还有多少盘小料任务(放置到双层线的D料架上)
        //         bigTask: 还有多少盘大料任务(放置到C料架上)
    }
}