Esempio n. 1
0
 /// <summary>
 /// 启动,软停止和硬停止都可用
 /// </summary>
 public void Start()
 {
     if (!isRunning)
     {
         isRunning = true;
         tcpServer.Start();
         //每两秒扫描一次命令缓冲区
         ScanActionTimer = YUtil.SetInterval(2000, () => {
             using (ActionLock.Lock()) {
                 //自动执行任务
                 var canClear = true;
                 foreach (var pair in ActionCache)
                 {
                     if (pair.Value != SmAction.NoAction && ActionClientDict.ContainsKey(pair.Key))
                     {
                         try {
                             var state = ActionClientDict[pair.Key];
                             tcpServer.Send(state, SmParamApi.BuildAlarmPackage(state.ModuleAddr, pair.Value));
                             Logger.Debug($"发送命令 {Enum.GetName(typeof(SmAction), pair.Value)} 成功 {pair.Key}");
                             ActionCache[pair.Key] = SmAction.NoAction;
                         } catch {
                             canClear = false;
                             Logger.Error($"发送命令 {Enum.GetName(typeof(SmAction), pair.Value)} 异常 {pair.Key}", 24 * 3600);
                         }
                     }
                 }
                 if (canClear)
                 {
                     YUtil.ClearTimeout(ScanActionTimer);
                 }
             }
         });
     }
 }
Esempio n. 2
0
        /// <summary>
        /// 程序将在 totalSec 之后重启
        /// </summary>
        /// <param name="totalSec"></param>
        /// <param name="percent"></param>
        /// <param name="message"></param>
        void restartAppAfterSec(int totalSec, double percent, string message = "程序启动超时")
        {
            try {
                var latestLog = getAppLatestStartupLog();
                //连续启动失败次数越多,等待启动时间越长
                if (latestLog?.ContinueFailedTimes > 0 && !HmiConfig.IsDevUserEnv)
                {
                    totalSec = latestLog.ContinueFailedTimes * 10;
                }
                updateAppStartupLog(message);
            } catch (Exception e) {
                Logger.Error("启动日志出问题", e);
            }
            //显示重启提示
            var waitMessage = $"{message},将在 {totalSec} 秒后尝试重启";

            updateLoadingMessage(waitMessage, percent, 0);
            YUtil.SetInterval(1000, t => {
                var wait    = totalSec - t;
                waitMessage = $"{message},将在 {wait} 秒后尝试重启";
                updateLoadingMessage(waitMessage, percent, 0);
                if (wait <= 0)
                {
                    App.Restart();
                }
            }, totalSec);
        }
Esempio n. 3
0
        /// <summary>
        /// 配置文件加载之后才能对其初始化
        /// 1. 每隔指定时间(15分钟)关闭显示器
        /// 2. 每天8:00打开显示器
        /// 3. 定时上传Cpm到Mq
        /// </summary>
        public async Task Init()
        {
            JobManager.JobException += info => Logger.Error("An error just happened with a scheduled job: " + info.Exception);
            //自动关闭显示器
            await App.Store.Dispatch(sysEffects.StartCloseScreenTimer(new SysActions.StartCloseScreenTimer(HmiConfig.CloseScreenInterval)));

            //启动定时上传Cpms到Mq定时器
            await App.Store.Dispatch(mqEffects.StartUploadCpmsInterval(new MqActions.StartUploadCpmsInterval(HmiConfig.QueUpdateWebBoard, HmiConfig.UploadWebBoardInterval)));

            //定义完成一些额外的任务
            //YUtil.SetInterval(HmiConfig.UploadWebBoardInterval, () => {
            //    updateGrafana();
            //});

            //一小时缓存一次485状态
            YUtil.SetInterval(3600000, () => {
                persistCom485State();
            });

            //每天8点打开显示器
            Schedule(() => {
                App.Store.Dispatch(new SysActions.OpenScreen());
                App.Logger.Info("8 点开启显示器");
            }).ToRunEvery(1).Days().At(8, 0);

            JobManager.Initialize(this);
        }
Esempio n. 4
0
 /// <summary>
 /// 初始化
 /// </summary>
 public void Init()
 {
     eventHandlers = new Dictionary <Type, EventHandler <YEventArgs> >();
     eventHandlers[typeof(PipeReceived)] = whenPipeReceived;
     App.EventStore.Subscribe(eventHandlers);
     //HmiPro 软件保活
     YUtil.SetInterval(60000, keepHmiAlive);
     Logger = LoggerHelper.Create(GetType().ToString());
 }
Esempio n. 5
0
 void initStartUploadCpmsIntervalEffect()
 {
     StartUploadCpmsInterval =
         App.Store.asyncActionVoid <MqActions.StartUploadCpmsInterval>(async(dipatch, getState, instance) => {
         dipatch(instance);
         await Task.Run(() => {
             YUtil.SetInterval(instance.Interval, () => {
                 App.Store.Dispatch(UploadCpms(new MqActions.UploadCpms(getState().CpmState.OnlineCpmsDict, instance.QueueName)));
             });
         });
     });
 }
Esempio n. 6
0
        /// <summary>
        /// 初始化上面的 Effect
        /// </summary>
        /// <param name="sysService"></param>
        public SysEffects(SysService sysService)
        {
            UnityIocService.AssertIsFirstInject(GetType());
            Logger = LoggerHelper.CreateLogger(GetType().ToString());
            //启动http解析服务
            StartHttpSystem = App.Store.asyncAction <SysActions.StartHttpSystem, bool>(
                async(dispatch, getState, instance) => {
                dispatch(instance);
                var isStarted = await sysService.StartHttpSystem(instance);
                if (isStarted)
                {
                    App.Store.Dispatch(new SysActions.StartHttpSystemSuccess());
                }
                else
                {
                    App.Store.Dispatch(new SysActions.StartHttpSystemFailed());
                }
                return(isStarted);
            });
            //启动关闭显示器定时器
            StartCloseScreenTimer = App.Store.asyncActionVoid <SysActions.StartCloseScreenTimer>(
                async(dispatch, getState, instance) => {
                dispatch(instance);
                await Task.Run(() => {
                    if (CloseScrrenTimer != null)
                    {
                        YUtil.RecoveryTimeout(CloseScrrenTimer);
                    }
                    else
                    {
                        CloseScrrenTimer = YUtil.SetInterval(instance.Interval, () => {
                            App.Store.Dispatch(new SysActions.CloseScreen());
                        });
                    }
                });
            });

            //停止关闭显示器定时器
            StopCloseScrenTimer = App.Store.asyncActionVoid <SysActions.StopCloseScreenTimer>(
                async(dispatch, getState, instance) => {
                dispatch(instance);
                await Task.Run(() => {
                    if (CloseScrrenTimer != null)
                    {
                        YUtil.ClearTimeout(CloseScrrenTimer);
                    }
                });
            });
        }
Esempio n. 7
0
 /// <summary>
 /// 异步启动服务,将在线参数字典与AppState全局字典进行绑定
 /// </summary>
 /// <param name="ip"></param>
 /// <param name="port"></param>
 /// <returns></returns>
 public Task StartAsync(string ip, int port)
 {
     return(Task.Run(() => {
         if (SmParamTcp == null)
         {
             SmParamTcp = new YSmParamTcp(ip, port, LoggerHelper.CreateLogger("YSmParamTcp"));
             SmParamTcp.OnDataReceivedAction += whenSmActived;
             OnlineCpmDict = App.Store.GetState().CpmState.OnlineCpmsDict;
             //检查超时
             YUtil.SetInterval(HmiConfig.CpmTimeout, () => {
                 checkCpmTimeout(HmiConfig.CpmTimeout);
             });
         }
         SmParamTcp.Start();
     }));
 }
Esempio n. 8
0
        /// <summary>
        /// 程序将在 totalSec 秒后自动关闭
        /// </summary>
        void shutdownAppAfterSec(int totalSec, double percent, string message = "程序启动超时")
        {
            try {
                updateAppStartupLog(message);
            } catch {
            }

            YUtil.SetInterval(1000, t => {
                var wait        = totalSec - t;
                var waitMessage = $"{message},将在 {wait} 秒后关闭";
                updateLoadingMessage(waitMessage, percent, 0);
                if (wait <= 0)
                {
                    App.Shutdown();
                }
            }, totalSec);
        }
Esempio n. 9
0
        /// <summary>
        /// 周期的去ping模块的ip,更新其离线状态
        /// </summary>
        /// <param name="state"></param>
        /// <param name="intervalSec"></param>
        private static void updateCom485Interval(State state, int intervalSec)
        {
            void update()
            {
                foreach (var pair in state.Com485StatusDict)
                {
                    Ping ping = new Ping();
                    var  ret  = ping.Send(pair.Key, 2000);
                    if (ret?.Status != IPStatus.Success)
                    {
                        pair.Value.Status = SmSingleStatus.Offline;
                        pair.Value.Time   = DateTime.Now;
                    }
                }
            }

            Task.Run(() => {
                update();
                YUtil.SetInterval(intervalSec * 1000, update);
            });
        }
Esempio n. 10
0
        /// <summary>
        /// 配置文件加载成功之后执行的一些初始化
        /// </summary>
        async void afterConfigLoaded()
        {
            //== 初始化部分State
            updateLoadingMessage("正在初始化系统核心...", 0.5);
            App.Store.Dispatch(new ViewStoreActions.Init());
            App.Store.Dispatch(new CpmActions.Init());
            App.Store.Dispatch(new AlarmActions.Init());
            App.Store.Dispatch(new OeeActions.Init());
            App.Store.Dispatch(new DMesActions.Init());
            App.Store.Dispatch(new DpmActions.Init());

            var sysEffects = UnityIocService.ResolveDepend <SysEffects>();
            var cpmEffects = UnityIocService.ResolveDepend <CpmEffects>();
            var mqEffects  = UnityIocService.ResolveDepend <MqEffects>();

            updateLoadingMessage("正在连接服务器...", 0.55);
            var task = Task.Run(() => {
                mqEffects.Start();
            });
            //更新连接服务器的进度
            double p = 0.55;
            bool   isMqEffectsStarted = false;
            Timer  updateTimer        = null;

            updateTimer = YUtil.SetInterval(500, () => {
                if (!isMqEffectsStarted)
                {
                    p += 0.01;
                    updateLoadingMessage("正在连接服务器...", p, 0);
                    Logger.Debug("正在连接服务器..." + p.ToString("P1"));
                }
                if (isMqEffectsStarted || p > 0.64)
                {
                    YUtil.ClearTimeout(updateTimer);
                }
            });
            isMqEffectsStarted = Task.WaitAll(new[] { task }, 10000);
            YUtil.ClearTimeout(updateTimer);
            if (!isMqEffectsStarted)
            {
                updateLoadingMessage("连接 Mq 超时...", 0.6);
                App.Store.Dispatch(new SysActions.AddMarqueeMessage(SysActions.MARQUEE_CONECT_MQ_TIMEOUT, "Mq 连接超时"));
                restartAppAfterSec(10, 0.6, "连接 Mq 超时");
                return;
            }

            updateLoadingMessage("正在注册程序...", 0.65);
            if (!await YUtil.CheckHttpFileExist(HmiConfig.StaticServerUrl + "/verify.txt"))
            {
                updateLoadingMessage("程序启动失败,请联系管理员", 0.66);
                restartAppAfterSec(10, 0.66, "程序启动失败,请联系管理员");
                return;
            }
            UnityIocService.ResolveDepend <DMesCore>().Init();
            UnityIocService.ResolveDepend <AlarmCore>().Init();
            UnityIocService.ResolveDepend <CpmCore>().Init();
            UnityIocService.ResolveDepend <OeeCore>().Init();
            UnityIocService.ResolveDepend <DpmCore>().Init();
            UnityIocService.ResolveDepend <HookCore>().Init();


            //Http 命令解析
            updateLoadingMessage("正在启动Http服务...", 0.7);
            var starHttpSystem = App.Store.Dispatch(sysEffects.StartHttpSystem(new SysActions.StartHttpSystem($"http://+:{HmiConfig.CmdHttpPort}/")));

            //参数采集服务
            updateLoadingMessage("正在启动参数采集服务...", 0.75);
            var startCpmServer = App.Store.Dispatch(cpmEffects.StartServer(new CpmActions.StartServer(HmiConfig.CpmTcpIp, HmiConfig.CpmTcpPort)));

            //监听排产和来料
            updateLoadingMessage("正在启动监听排产服务...", 0.8);
            Dictionary <string, Task <bool> > startListenMqDict = new Dictionary <string, Task <bool> >();

            foreach (var pair in MachineConfig.MachineDict)
            {
                //监听排产任务
                var stQueueName = @"QUEUE_" + pair.Key;
                var stTask      = App.Store.Dispatch(mqEffects.StartListenSchTask(new MqActions.StartListenSchTask(pair.Key, stQueueName)));
                startListenMqDict[stQueueName] = stTask;
                //监听来料
                var smQueueName = $@"JUDGE_MATER_{pair.Key}";
                var smTask      = App.Store.Dispatch(mqEffects.StartListenScanMaterial(new MqActions.StartListenScanMaterial(pair.Key, smQueueName)));
                startListenMqDict[smQueueName] = smTask;
            }

            //监听人员打卡
            updateLoadingMessage("正在启动监听人员打卡...", 0.85);
            var empRfidTask = App.Store.Dispatch(mqEffects.StartListenEmpRfid(new MqActions.StartListenEmpRfid(MachineConfig.HmiName + "_employee", HmiConfig.TopicEmpRfid)));

            startListenMqDict["rfidEmpTask"] = empRfidTask;

            //监听轴号卡
            updateLoadingMessage("正在启动监听盘卡扫描...", 0.90);
            var axisRfidTask = App.Store.Dispatch(mqEffects.StartListenAxisRfid(new MqActions.StartListenAxisRfid(MachineConfig.HmiName + "_axis", HmiConfig.TopicListenHandSet)));

            startListenMqDict["rfidAxisTask"] = axisRfidTask;

            //监听机台命令
            updateLoadingMessage("正在启动监听机台命令...", 0.92);
            var cmdTask = App.Store.Dispatch(mqEffects.StartListenCmd(new MqActions.StartListenCmd(MachineConfig.HmiName + "_cmd", HmiConfig.TopicCmdReceived)));

            startListenMqDict["cmdTask"] = cmdTask;

            updateLoadingMessage("正在启动系统核心服务...", 0.95);
            var tasks = new List <Task <bool> >()
            {
                starHttpSystem, startCpmServer
            };

            tasks.AddRange(startListenMqDict.Values);
            //检查各项任务启动情况
            await Task.Run(() => {
                //等等所有任务完成
                var isStartedOk = Task.WaitAll(tasks.ToArray(), 30000);
                if (!isStartedOk)
                {
                    var message = "系统核心启动超时,请检查网络连接";
                    updateLoadingMessage(message, 0.95);
                    restartAppAfterSec(10, 0.95, "系统核心启动超时");
                    return;
                }
                //是否启动完成Cpm服务
                var isCpmServer = startCpmServer.Result;
                if (!isCpmServer)
                {
                    var message = "参数采集核心启动失败";
                    updateLoadingMessage(message, 0.95, 0);
                    restartAppAfterSec(10, 0.95, message);
                    return;
                }
                //是否启动完成Http解析系统
                var isHttpSystem = starHttpSystem.Result;
                if (!isHttpSystem)
                {
                    var message = "Http 核心启动失败";
                    updateLoadingMessage(message, 0.95, 0);
                    restartAppAfterSec(10, 0.95, message);
                    return;
                }
                //是否完成监听Mq
                foreach (var pair in startListenMqDict)
                {
                    var isStartListenMq = pair.Value.Result;
                    var mqKey           = pair.Key.ToUpper();
                    if (!isStartListenMq)
                    {
                        string failedMessage = string.Empty;
                        if (mqKey.Contains("QUEUE"))
                        {
                            failedMessage = $"监听Mq 排产队列 {pair.Key} 失败";
                        }
                        else if (mqKey.Contains("JUDGE_MATER"))
                        {
                            failedMessage = $"监听Mq 扫描来料队列 {pair.Key} 失败";
                        }
                        else if (mqKey.Contains("RFIDEMP"))
                        {
                            failedMessage = $"监听mq 人员打卡 数据失败";
                        }
                        else if (mqKey.Contains("RFIDAXIS"))
                        {
                            failedMessage = $"监听Mq 线盘卡失败";
                        }
                        else if (mqKey.Contains("CMD"))
                        {
                            failedMessage = $"监听Mq 机台命令失败";
                        }
                        if (!string.IsNullOrEmpty(failedMessage))
                        {
                            updateLoadingMessage(failedMessage, 0.95, 0);
                            restartAppAfterSec(10, 0.95, failedMessage);
                            return;
                        }
                    }
                }
                if (HmiConfig.IsDevUserEnv)
                {
                    updateLoadingMessage("系统核心启动完毕,正在渲染界面...", 1, 0);
                    App.Store.Dispatch(new SysActions.AppInitCompleted());
                    return;
                }
                var percent = 0.95;
                YUtil.SetInterval(300, t => {
                    percent += 0.01;
                    updateLoadingMessage("系统核心启动完毕,正在渲染界面...", percent, 0);
                    if (t == 5 || percent >= 1)
                    {
                        App.Store.Dispatch(new SysActions.AppInitCompleted());
                    }
                }, 5);
            });

            //update: 2018-3-28
            // 将调度器最后启用,这些调度器需要依赖比较多,但本身不提供依赖
            updateLoadingMessage("正在启动调度器...", 0.98);
            await UnityIocService.ResolveDepend <SchCore>().Init();
        }