static void Main(string[] args) { if (args?.Length == 0) { args = new string[] { "StartHmiPro", "update-app", "clear-task" }; } var(s, d) = YUtil.CreateDynamic(); s.hello = "world"; Console.WriteLine(d["hello"]); var cmd = new Cmd(); cmd.Action = args[0]; cmd.Args = new { IsForced = true }; var hmis = loadHmi(YUtil.GetAbsolutePath(".\\Global.xls"), "Ip配置"); int asylumPort = 9988; int hmiPort = 8899; foreach (var pair in hmis) { string ip = pair.Value; var name = pair.Key; var hmiProUrl = $"http://{ip}:{hmiPort}"; var asylumUrl = $"http://{ip}:{asylumPort}"; var url = asylumUrl; SendToAsylum(url, cmd, name); //var url = hmiProUrl; //SendToHmiPro(url, args[2], name); } YUtil.ExitWithQ(); }
/// <summary> /// 计算Oee的开机率,Or /// </summary> /// <returns></returns> public float?CalcOeeTimeEff(string machineCode, IList <MachineState> machineStates) { float?timeEff = null; float stateSpeed = 0; stateSpeed = App.Store.GetState().CpmState.StateSpeedDict[machineCode]; //删除上一班的机台状态数据 var workTime = YUtil.GetKeystoneWorkTime(); removeBeforeWorkTime(machineStates, workTime); var runTimeSec = getMachineRunTimeSec(machineStates, stateSpeed); var debugTimeSec = getMachineDebugTimeSec(); //计算时间效率 if (runTimeSec < 0) { Logger.Error($"计算时间效率失败,有效时间 {runTimeSec} < 0 "); } else { var cpms = App.Store.GetState().CpmState.OnlineCpmsDict[machineCode]; cpms[DefinedParamCode.RunTime].Value = TimeSpan.FromSeconds(runTimeSec - debugTimeSec).TotalHours; cpms[DefinedParamCode.DutyTime].Value = (DateTime.Now - workTime).TotalHours; cpms[DefinedParamCode.StopTime].Value = (double)cpms[DefinedParamCode.DutyTime].Value - (double)cpms[DefinedParamCode.RunTime].Value; timeEff = (float)((runTimeSec - debugTimeSec) / (DateTime.Now - workTime).TotalSeconds); Logger.Debug($"当班时间:{(DateTime.Now - workTime).TotalHours.ToString("0.00")} 小时,机台运行时间 {cpms[DefinedParamCode.RunTime].GetFloatVal().ToString("0.00")} 小时"); } return(timeEff); }
/// <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); }
/// <summary> /// 逻辑上的停止,推荐使用 /// </summary> public void StopSoft() { isRunning = false; //停止对命令缓冲的扫描 YUtil.ClearTimeout(ScanActionTimer); ScanActionTimer = null; }
/// <summary> /// 启动 Hmi Pro /// </summary> /// <param name="data"></param> /// <returns></returns> ExecRest startHmiPro(object data) { var start = (CmdActions.StartHmiPro)data; var rest = new ExecRest(); try { rest.DebugMessage = YUtil.CheckProcessIsExist(hmiProName) ? "HmiPro 进程存在" : "HmiPro 进程不存在"; //强制启动 if (start.IsForced) { YUtil.KillProcess(hmiProName); YUtil.Exec(hmiProPath, start.StartArgs); rest.Message = "强制启动 HmiPro 成功"; //只有当进程不存在的时候才启动 } else if (!YUtil.CheckProcessIsExist(hmiProName)) { YUtil.Exec(hmiProPath, start.StartArgs); rest.Message = "启动 HmiPro 成功"; } rest.Code = ExecCode.Ok; } catch (Exception e) { rest.Message = "启动 HmiPro 失败"; rest.Code = ExecCode.StartHmiProFailed; rest.DebugMessage = e.Message; } return(rest); }
/// <summary> /// 机台命令处理 /// </summary> /// <param name="json"></param> public void CmdAccept(string json) { try { var mqCmds = JsonConvert.DeserializeObject <List <AppCmd> >(json); var mqCmd = mqCmds.FirstOrDefault(m => MachineConfig.MachineDict.Keys.Contains(m.machineCode.ToUpper())); if (mqCmd == null) { return; } //机台过滤 if (MachineConfig.MachineDict.Keys.Contains(mqCmd.machineCode.ToUpper())) { mqCmd.machineCode = mqCmd.machineCode.ToUpper(); //指定执行时间 if (mqCmd.execTime.HasValue) { var execTime = YUtil.UtcTimestampToLocalTime(mqCmd.execTime.Value); Console.WriteLine($"任务将在 {execTime.ToString("G")} 执行"); JobManager.AddJob(() => { App.Store.Dispatch(new MqActions.CmdAccept(mqCmd.machineCode, mqCmd)); }, (s) => s.ToRunOnceAt(execTime)); } else { App.Store.Dispatch(new MqActions.CmdAccept(mqCmd.machineCode, mqCmd)); } } } catch (Exception e) { Logger.Error("处理机台命令异常,命令为:" + json, e); } }
public void SyncTime() { Task.Run(() => { try { //获取服务器时间 var ntpTime = YUtil.GetNtpTime(HmiConfig.NtpIp); App.StartupLog.SyncServerTime = ntpTime; //时间差超过10秒才同步时间 if (Math.Abs((DateTime.Now - ntpTime).TotalSeconds) > 10) { YUtil.SetLoadTimeByDateTime(ntpTime); } App.Store.Dispatch(new SysActions.ShowNotification(new SysNotificationMsg() { Title = "通知", Content = "同步时间成功" })); } catch (Exception e) { App.Store.Dispatch(new SysActions.ShowNotification(new SysNotificationMsg() { Title = "警告", Content = "同步时间失败" })); } }); }
public bool WriteCpms(string measurement, Cpm[] cpms, int offset, int count) { if (offset + count >= cpms.Length) { return(false); } List <string> paramList = new List <string>(); for (int i = offset; i < count + offset; i++) { var cpm = cpms[i]; if (cpm.ValueType != SmParamType.Signal) { continue; } var timeStamp = ""; //fixed:不能插入时间 timeStamp = YUtil.GetUtcTimestampMs(cpm.PickTime) + "000000"; var param = $"{measurement},param={cpm.Name.Replace(" ","")} value={cpm.Value} {timeStamp}"; paramList.Add(param); } var resp = WriteMulti(paramList.ToArray()); if (resp.Length > 0) { Console.WriteLine(Encoding.UTF8.GetString(resp)); return(false); } return(true); }
/// <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); } } }); } }
public bool WriteCpms(string measurement, params Cpm[] cpms) { List <string> paramList = new List <string>(); foreach (var cpm in cpms) { if (cpm.ValueType != SmParamType.Signal) { continue; } var timeStamp = ""; //fixed:不能插入时间 timeStamp = YUtil.GetUtcTimestampMs(cpm.PickTime) + "000000"; var param = $"{measurement},param={cpm.Name} value={cpm.Value} {timeStamp}"; paramList.Add(param); } var resp = WriteMulti(paramList.ToArray()); if (resp.Length > 0) { Console.WriteLine(Encoding.UTF8.GetString(resp)); return(false); } return(true); }
/// <summary> /// 获取写入 InfluxDb 的字符串 /// 使用 StringBuilder 为了防止内存溢出 /// </summary> /// <param name="measurement"></param> /// <param name="cpms"></param> /// <param name="pickTime"></param> /// <returns></returns> public StringBuilder GetCpms2WriteString(string measurement, List <Cpm> cpms, DateTime pickTime) { StringBuilder builder = new StringBuilder(); builder.Append($"{measurement},tag=采集参数 "); var timestamp = YUtil.GetUtcTimestampMs(pickTime) + "000000"; bool valid = false; foreach (var cpm in cpms) { if (cpm.ValueType != SmParamType.Signal) { continue; } //fix: 由于名字空格不能插入的情况 builder.Append($"{cpm.Name.Replace(" ", "")}={cpm.Value},"); valid = true; } //无有效参数的时候返回空的 sb if (valid == false) { builder.Clear(); return(builder); } builder.Remove(builder.Length - 1, 1); builder.Append($" {timestamp}"); builder = builder.Replace("/", string.Empty).Replace("\\", string.Empty); return(builder); }
/// <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); }
/// <summary> /// 执行更新 /// </summary> public void StartUpdate() { bool needRestart = false; StringBuilder sb = new StringBuilder(); foreach (var name in GlobalConfig.UpdateMustReartHmiNames) { if (MachineConfig.HmiName.Contains(name)) { needRestart = true; } sb.Append(name).Append(","); } if (!needRestart) { //关闭监视进程 YUtil.StopWinService(HmiConfig.DaemonServiceName); YUtil.KillProcess(HmiConfig.AsylumProcessName); AppUpdater.StartExternalUpdater(); } else { YUtil.RestartPC(); } }
/// <summary> /// 更新启动日志 /// </summary> /// <param name="startFailedReason">启动失败原因</param> private void updateAppStartupLog(string startFailedReason) { //设置 HmiName var localIp = YUtil.GetAllIps().FirstOrDefault(ip => ip.Contains("188.")); var hmiName = !string.IsNullOrEmpty(MachineConfig.HmiName) ? MachineConfig.HmiName : localIp ?? "Unknowns"; if (!string.IsNullOrEmpty(App.StartupLog.HmiName)) { App.StartupLog.HmiName = hmiName; } var lastLog = getAppLatestStartupLog(); //增加启动失败次数 if (lastLog != null) { App.StartupLog.ContinueFailedTimes = ++lastLog.ContinueFailedTimes; } else { App.StartupLog.ContinueFailedTimes = 1; } App.StartupLog.StartFailedReason = startFailedReason; Logger.Error(startFailedReason + " -->" + JsonConvert.SerializeObject(App.StartupLog)); //保存到 Sqlite using (var ctx = SqliteHelper.CreateSqliteService()) { ctx.StartupLogs.Add(App.StartupLog); ctx.SaveChanges(); } //上传到 MongoDB var mongoClient = MongoHelper.GetMongoService(); mongoClient.GetDatabase(MongoHelper.LogsDb).GetCollection <StartupLog>(MongoHelper.StartupLogsCollection).InsertOneAsync(App.StartupLog); }
/// <summary>s /// 设置程序启动时间 /// </summary> public App() { StartupLog = new StartupLog() { StartTime = DateTime.Now, AppVersion = YUtil.GetAppVersion(Assembly.GetExecutingAssembly()), SyncServerTime = DateTime.Now }; AppState.ExectedActions["[App] Started"] = DateTime.Now; }
/// <summary> /// 常用调试信息 /// </summary> /// <param name="message">输出内容</param> /// <param name="outFile">是否输出到温度,默认是</param> /// <param name="consoleColor">Console输出的颜色,默认白色</param> /// <param name="outMinGapSec">日志打印最小时间间隔秒数</param> public void Info(string message, bool outFile = true, ConsoleColor consoleColor = ConsoleColor.White, int outMinGapSec = 0) { var lineNum = YUtil.GetCurCodeLineNum(2); Console.ForegroundColor = consoleColor; Info(DefaultLocation + $"[{lineNum}]行", message, outFile, outMinGapSec); Console.ForegroundColor = ConsoleColor.White; }
public void ShowLogFoler() { Task.Run(() => { ShowPasswordForm(() => { YUtil.Exec(HmiConfig.LogFolder, ""); }); }); }
/// <summary> /// 关闭Tcp从而停止,不推荐使用 /// </summary> public void StopHard() { isRunning = false; tcpServer.Stop(); //停止对命令缓冲的扫描 YUtil.ClearTimeout(ScanActionTimer); ScanActionTimer = null; }
/// <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()); }
public MainWindow() { InitializeComponent(); // 初始化主窗口 InitializeMainWindow(); // 设置通知栏图标 InitailizeNotifyIcon(); try { // 开发电脑上面就不用自启了 // 设置开机自启 if (!YUtil.GetWindowsUserName().ToUpper().Contains("SOMIAR")) { YUtil.SetAppAutoStart("PanyuVisualSystem", true); } else { UIMessageBox.Show("提示", "开发电脑无需自启", 5000); } } catch { UIMessageBox.Show("异常", "设置启动异常", 5000); // ignored } try { // 番禺的防火墙服务默认是禁用 // 这样就会封掉所有端口,所以只能打开防火墙服务,然后关闭防火墙才行 // 当然防火墙的状态是设置的为关闭 YUtil.SetWinServiceStartupType("MpsSvc", ServiceStartMode.Automatic); YUtil.StartWinService("MpsSvc"); } catch { // ignored } // 检查网络连接 if (OnlineDataCenter.IsNetwork2ServerOK()) { InitAndSetupMachineWindow(); try { // 同步服务器时间 var time = YUtil.GetNtpTime(Configuration.ServerIp); if (Math.Abs((DateTime.Now - time).TotalSeconds) > 10) { YUtil.SetLoadTimeByDateTime(time); } } catch { // ignored } } else { Task.Run(() => { SustainedNetworkTest(null); }); } }
/// <summary> /// 关闭程序 /// </summary> public new static void Shutdown() { Current.Dispatcher.Invoke(() => { ConsoleHelper.Hide(); try { YUtil.KillProcess(Process.GetCurrentProcess().ProcessName); } catch { // ignored } }); }
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))); }); }); }); }
/// <summary> /// 异步从服务器下载 PDF 文件 /// </summary> /// <param name="filename"></param> private async void downloadWorkSheetPDFAsync(string filename) { await Task.Run(() => { if (YUtil.DownloadFtpFile($"ftp://{Configuration.ServerIp}/{filename}", PdfDirPath + filename)) { OnChangeProductionProcessPdf(filename); } else { UIMessageBox.Show("错误", $"下载工艺文件失败,请检查 [{filename}] 是否存在于服务器", 5000); } }); }
/// <summary> /// 重启软件 /// </summary> public static void Restart() { Current.Dispatcher.Invoke(() => { //利用脚本启动 var startupParam = string.Join(" ", CmdOptions.StartupEventArgs.Args); ConsoleHelper.Hide(); YUtil.Exec(AssetsHelper.GetAssets().BatStartApp, startupParam, ProcessWindowStyle.Hidden); try { YUtil.KillProcess(Process.GetCurrentProcess().ProcessName); } catch { // ignored } }); }
/// <summary> /// 检验是否为第一次注入 /// </summary> /// <param name="type"></param> /// <returns></returns> public static bool AssertIsFirstInject(Type type) { if (!injectOnceCheckDictionary.ContainsKey(type)) { injectOnceCheckDictionary[type] = true; } else { injectOnceCheckDictionary[type] = false; var lineNum = YUtil.GetCurCodeLineNum(2); throw new Exception(type + $"已经被注入了,请勿重复注入此全局依赖 [{lineNum}] 行"); } return(injectOnceCheckDictionary[type]); }
/// <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); } }); }); }
public static void Load(string path) { var config = YUtil.GetJsonObjectFromFile <Dictionary <string, object> >(path); YUtil.SetStaticField(typeof(HmiConfig), config); bool isDevUserEnv = DevUser.ToLower().Contains(YUtil.GetWindowsUserName().ToLower()); var genDict = new Dictionary <string, object>(); genDict[nameof(IsDevUserEnv)] = isDevUserEnv; YUtil.SetStaticField(typeof(HmiConfig), genDict); YUtil.ValidRequiredConfig(typeof(HmiConfig)); CraftBomZhsDict = new Dictionary <string, string>(); }
/// <summary> /// 关闭 HmiPro /// 目前仅支持强制关闭 /// </summary> /// <param name="data"></param> /// <returns></returns> ExecRest closeHmiPro(object data) { var close = (CmdActions.CloseHmiPro)data; var rest = new ExecRest(); try { YUtil.KillProcess(hmiProName); rest.Message = "关闭 HmiPro 成功"; rest.Code = ExecCode.Ok; } catch (Exception e) { rest.DebugMessage = e.Message; rest.Code = ExecCode.CloseHmiProFailed; } return(rest); }
public static MqAlarm CreateOneAlarm(int code = -1) { return(new MqAlarm() { alarmType = AlarmType.OtherErr, axisCode = "GD2017122701ls01", code = code, CpmName = "直径", message = "直径值超过Plc设定的最大值", time = YUtil.GetUtcTimestampMs(DateTime.Now), meter = 1103.3f, workCode = "GD2017122701", machineCode = MachineConfig.MachineDict.First().Key }); }
/// <summary> /// 向某个ip发送命令,这里的ip必须是底层可以执行动作的ip /// </summary> /// <param name="ip"></param> /// <param name="action"></param> public void SendAction(string ip, SmAction action) { using (ActionLock.Lock()) { if (ActionClientDict.TryGetValue(ip, out var state)) { try { tcpServer.Send(state, SmParamApi.BuildAlarmPackage(state.ModuleAddr, action)); Logger.Debug($"发送命令 {Enum.GetName(typeof(SmAction), action)} 成功 {ip}"); ActionCache[ip] = SmAction.NoAction; } catch { ActionCache[ip] = action; YUtil.RecoveryTimeout(ScanActionTimer); } } } }