public void Start() { if (IsRuning) { return; } queue = new BlockingCollection <PumpCommand>(); task = new Task(() => { foreach (PumpCommand item in queue.GetConsumingEnumerable()) { try { Excute(item); } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("二供-命令消费器消费过程中出错:" + e.Message + "堆栈:" + e.StackTrace); } } }, TaskCreationOptions.LongRunning); task.Start(); IsRuning = true; }
private string[] LoadPumpJZOPCServerNames() { string sql = ""; switch (type) { case OPCClientManagerType.Pump: sql = "select distinct t1.FOPCServerName from Pump t,pumpjz t1 where (t.是否删除 = 0 or t.是否删除 is null) and (t1.是否删除 = 0 or t1.是否删除 is null) and t1.PumpJZReadMode = 'OPC';"; break; case OPCClientManagerType.Scada: sql = "select distinct FOPCServerName from SCADA_Station where ReadMode = 'OPC';"; break; } DataTable dt = DBUtil.ExecuteDataTable(sql, out string err); if (!string.IsNullOrEmpty(err)) { TraceManagerForOPC.AppendErrMsg("加载机组 OPCServerName 出错" + err); return(null); } List <string> r = new List <string>(); foreach (DataRow dr in dt.Rows) { r.Add(DataUtil.ToString(dr["FOPCServerName"])); } return(r.ToArray()); }
// 连接/断开连接 OPC 服务器 private bool Connect(bool silent = false) { if (_isOpcConnected) { return(true); } try { // KingView.View 或 Kepware.KepServerEX.V6 _client = new OPCServer(); _client.Connect(this._progId, this._hostIp); if (_client.ServerState != (int)OPCServerState.OPCRunning) { return(false); } BuildGroupsAndTags(); _isOpcConnected = true; return(true); } catch (Exception e) { if (!silent) { TraceManagerForOPC.AppendErrMsg("连接OPC服务器 " + this._progId + " 失败: " + e.Message); } return(false); } }
public void Stop() { if (!IsRuning) { return; } // 先完成添加 queue.CompleteAdding(); DateTime time1 = DateTime.Now; while (queue.Count > 0) { Thread.Sleep(1); // 最多等待10秒避免关不掉 if (DateTime.Now - time1 > TimeSpan.FromSeconds(10)) { TraceManagerForOPC.AppendErrMsg("二供-命令消费器关闭超时丢弃了" + queue.Count.ToString() + "条任务"); break; } } while (queue.Count > 0) { // 等了十秒还没听,队列全部元素废弃 queue.Take(); } queue = null; Task.WaitAll(task); task.Dispose(); task = null; IsRuning = false; }
public void Stop() { if (!IsRuning) { return; } try { // Scada-OPC通信服务 if (opcScadaService != null) { opcScadaService.Stop(); if (!opcScadaService.IsRuning) { TraceManagerForWeb.AppendDebug("Scada-OPC通信服务停止成功"); this.opcScadaService = null; } else { TraceManagerForWeb.AppendErrMsg("Scada-OPC通信服务停止失败"); } } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("Scada-OPC通信服务停止失败:" + e.Message); } IsRuning = false; }
public void Stop() { try { // 点表采集者服务 if (stationCollecter != null) { stationCollecter.Stop(); if (!stationCollecter.IsRuning) { TraceManagerForOPC.AppendDebug("点表采集管理服务已停止"); this.stationCollecter = null; } else { TraceManagerForOPC.AppendErrMsg("点表采集管理服务停止失败"); } } // 命令消费器 if (commandCustomer != null) { commandCustomer.Stop(); if (!commandCustomer.IsRuning) { TraceManagerForOPC.AppendDebug("命令消费器已停止"); this.commandCustomer = null; } else { TraceManagerForOPC.AppendErrMsg("命令消费器停止失败"); } } //OPC客户端管理服务 if (opcClientManager != null) { opcClientManager.Stop(); if (!opcClientManager.IsRuning) { TraceManagerForOPC.AppendDebug("OPC客户端管理服务已停止"); this.opcClientManager = null; } else { TraceManagerForOPC.AppendErrMsg("OPC客户端管理服务停止失败"); } } } catch { } IsRuning = false; }
public void Start(out string errMsg) { // 子服务启动失败,应该不影响其他子服务 errMsg = ""; string err = ""; if (!LoadConfig(out errMsg)) { return; } try { // 二供报警服务 if (this.runPumpAlarmService == 1) { pumpAlarmService = new PumpAlarmService(Config.projectConfigPath); pumpAlarmService.Start(out err); if (pumpAlarmService.IsRuning) { LogManager.AppendInfo(ServerTypeName.PumpAlarm, "二供报警服务已经全部启动"); } else { errMsg = "二供报警服务启动失败:" + err; } } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("二供报警服务启动失败:" + e.Message); } try { // OPC服务 if (this.runOPCServiceFlag == 1) { opcDataService = new OPCDataService(); opcDataService.Start(out err); if (opcDataService.IsRuning) { LogManager.AppendInfo(ServerTypeName.OPC, "OPC接入服务已经全部启动"); } else { errMsg = "OPC接入服务启动失败:" + err; } } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("OPC接入服务启动失败:" + e.Message); } IsRuning = true; }
// 任务分发口 public void ExcuteCollect() { try { if (!ExcuteCollectHandle(out string errMsg)) { TraceManagerForOPC.AppendWarning("站点定时采集任务执行失败;" + errMsg); } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("站点定时采集任务执行失败--" + e.Message + "堆栈:" + e.StackTrace); } }
public void Append(PumpCommand command) { if (!IsRuning) { return; } if (queue.IsAddingCompleted) { return; } if (queue.Count > 4096) { TraceManagerForOPC.AppendErrMsg("二供-命令消费队列到达上限无法插入"); return; } queue.Add(command); }
public void Stop() { try { // OPC服务 if (this.opcDataService != null) { this.opcDataService.Stop(); if (this.opcDataService.IsRuning) { LogManager.AppendErrMsg(ServerTypeName.Dispatch, "OPC接入服务停止失败"); } else { LogManager.AppendInfo(ServerTypeName.Dispatch, "OPC接入服务已经全部停止"); } this.opcDataService = null; } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("OPC接入服务停止失败:" + e.Message); } try { // 二供报警服务 if (this.pumpAlarmService != null) { this.pumpAlarmService.Stop(); if (this.pumpAlarmService.IsRuning) { LogManager.AppendErrMsg(ServerTypeName.Dispatch, "二供报警服务停止失败"); } else { LogManager.AppendInfo(ServerTypeName.Dispatch, "二供报警服务已经全部停止"); } this.pumpAlarmService = null; } } catch (Exception e) { LogManager.AppendErrMsg(ServerTypeName.Dispatch, "二供报警服务停止失败:" + e.Message); } IsRuning = false; }
private void StartAsyncRefreshFromDevice() { _timerRefreshFromDevice = new System.Timers.Timer(); _timerRefreshFromDevice.Interval = 1 * 60 * 1000; _timerRefreshFromDevice.Elapsed += (o, e) => { try { if (this.IsOpcConnected) { _group.AsyncRefresh((short)OPCDataSource.OPCDevice, 1002, out int cancelId); } } catch (Exception ee) { TraceManagerForOPC.AppendErrMsg("OPC DA定时从客户端刷新数据异常" + ee.Message); } }; _timerRefreshFromDevice.Enabled = true; }
// 定时采集任务执行体 public bool ExcuteCollectHandle(out string errMsg) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 // 加载需要采集点 if (!LoadCache(out List <PumpJZ> jzs, out errMsg)) { return(false); } if (jzs.Count == 0) { errMsg = "机组表没有读取模式为OPC的有效机组";; return(false); } // 从OPC缓存中取数 if (!Collect(ref jzs, out errMsg)) { return(false); } // 存入到数据库 string saveSQL = GetSavePointsSQL(jzs); if (string.IsNullOrWhiteSpace(saveSQL)) { errMsg = string.Format(@"采集OPC-机组数量{0}获取存入数据库SQL失败", jzs.Count); return(false); } DBUtil.ExecuteNonQuery(saveSQL, out string err); stopwatch.Stop(); // 停止监视 TimeSpan timespan = stopwatch.Elapsed; // 获取当前实例测量得出的总时间 double milliseconds = timespan.TotalMilliseconds; // 总毫秒数 if (!string.IsNullOrWhiteSpace(err)) { errMsg = "更新OPC-二供实时数据失败" + ",耗时:" + milliseconds.ToString() + "毫秒," + err; return(false); } TraceManagerForOPC.AppendDebug("更新OPC-二供实时数据成功" + ",耗时:" + milliseconds.ToString() + "毫秒"); return(true); }
public void ExcuteReload() { try { if (!ExcuteReloadHandle(out string errMsg)) { CommandManager.MakeFail(errMsg, ref requestCommand); CommandManager.CompleteCommand(requestCommand); TraceManagerForCommand.AppendWarning(requestCommand.message); return; } CommandManager.MakeSuccess("重载站点数据命令成功,SCADA-OPC数据已更新", ref requestCommand); CommandManager.CompleteCommand(requestCommand); TraceManagerForCommand.AppendInfo("重载站点数据命令成功,SCADA-OPC数据已更新"); } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("站点主动采集任务执行失败--" + e.Message + "堆栈:" + e.StackTrace); SendError("站点主动采集任务执行失败--" + e.Message); } }
public void ExcuteWrite() { try { if (!ExcuteWriteHandle(out string errMsg, out string info)) { CommandManager.MakeFail(errMsg, ref requestCommand); CommandManager.CompleteCommand(requestCommand); TraceManagerForCommand.AppendErrMsg(requestCommand.message); return; } CommandManager.MakeSuccess(info, ref requestCommand); CommandManager.CompleteCommand(requestCommand); TraceManagerForCommand.AppendInfo(info); } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("站点写值任务执行失败--" + e.Message + "堆栈:" + e.StackTrace); SendError("站点写值任务执行失败--" + e.Message); } }
public void Start() { if (IsRuning) { return; } // 初始化实时表 PumpJZDataOper.Instance.InitPumpRealData(out string errMsg); if (!string.IsNullOrWhiteSpace(errMsg)) { TraceManagerForOPC.AppendErrMsg(errMsg); return; } // 开启定时工作者 timer = new System.Timers.Timer(); timer.Interval = Config.pumpConfig.PointsCollectInterVal * 1000; timer.Elapsed += (o, ee) => { try { // 采集缓存中机组关联的点表信息 Excute(); } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("泵站表采集器异常" + e.Message); } }; timer.Enabled = true; IsRuning = true; // 开启之后就异步执行一次 Action action = Excute; action.BeginInvoke(null, null); }
// 定时采集任务执行体 public bool ExcuteCollectHandle(out string errMsg) { errMsg = ""; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 // 加载需要采集点 if (!LoadCache(out Dictionary <int, Station> dicStations, out errMsg)) { return(false); } // 从OPC缓存中取数 if (!Collect(ref dicStations, out errMsg)) { return(false); } // 存入到数据库 string saveSQL = GetSavePointsSQL(dicStations); if (string.IsNullOrWhiteSpace(saveSQL)) { errMsg = string.Format(@"采集OPC-站点数量{0}获取存入数据库SQL失败", dicStations.Count); return(false); } DBUtil.ExecuteNonQuery(saveSQL, out string err); stopwatch.Stop(); // 停止监视 TimeSpan timespan = stopwatch.Elapsed; // 获取当前实例测量得出的总时间 double milliseconds = timespan.TotalMilliseconds; // 总毫秒数 if (!string.IsNullOrWhiteSpace(err)) { errMsg = "更新OPC-SCADA实时数据失败" + ",耗时:" + milliseconds.ToString() + "毫秒," + err; return(false); } TraceManagerForOPC.AppendDebug("更新OPC-SCADA实时数据成功" + ",耗时:" + milliseconds.ToString() + "毫秒"); return(true); }
// 枚举本地 OPC public static string[] GetLocalServer() { List <string> serverName = new List <string>(); // 获取本地计算机上的 OPCServerName try { OPCServer server = new OPCServer(); object serverList = server.GetOPCServers(); foreach (string turn in (Array)serverList) { serverName.Add(turn.ToLower()); } } catch (Exception ex) { TraceManagerForOPC.AppendErrMsg(ex.Message); return(null); } return(serverName.ToArray()); }
// 控制入口 public bool Write(string tagName, object value, out string errMsg) { errMsg = ""; try { // 为避免 COM 对象的并发访问, 再建一个连接 OPCServer client = new OPCServer(); client.Connect(this._progId, this._hostIp); OPCGroup group = client.OPCGroups.Add("WritingGroup"); OPCItem item = group.OPCItems.AddItem(tagName, 1); int[] serverHandle = new int[] { 0, item.ServerHandle }; object[] writingValue = new object[] { null, value }; group.SyncWrite(1, serverHandle, writingValue, out Array error); client.Disconnect(); // 据推测故障码是 COM 函数返回值, 0 表示正常 int errorCode = Convert.ToInt32(error.GetValue(1)); if (errorCode != 0) { errMsg = this._progId + "的条目: " + tagName + " 写入失败; " + errorCode; return(false); } return(true); } catch (Exception ex) { errMsg = this._progId + "的条目: " + tagName + "写入失败: " + ex.Message + "\n" + ex.StackTrace; TraceManagerForOPC.AppendErrMsg(errMsg); return(false); } }
private void Disconnect() { try { _isOpcConnected = false; if (_client != null) { lock (_client) _client.Disconnect(); _client = null; } _group = null; lock (_tagNamedIndex) { _tagNamedIndex.Clear(); } lock (_tagClientHandleIndex) { _tagClientHandleIndex.Clear(); } lock (_tagServerHandleIndex) { _tagServerHandleIndex.Clear(); } } catch (Exception ex) { TraceManagerForOPC.AppendErrMsg("OPC 客户端主动下线失败: " + ex.Message); } }
public void Stop() { if (opcCaches == null) { return; } foreach (string key in opcCaches.Keys) { OpcDaClient opc = opcCaches[key]; if (opc == null) { continue; } try { opc.Stop(); TraceManagerForOPC.AppendDebug(key + "已断开连接"); } catch { } } opcCaches = null; IsRuning = false; }
public void Start(out string errMsg) { errMsg = ""; if (IsRuning) { return; } try { // Scada-OPC通信服务 if (opcScadaService != null) { opcScadaService.Stop(); } opcScadaService = new OPCScadaService(Config.projectConfigPath); opcScadaService.Start(out errMsg); if (opcScadaService.IsRuning) { TraceManagerForOPC.AppendDebug("Scada-OPC通信服务已经打开"); } else { errMsg = "Scada-OPC通信服务打开失败"; Stop(); return; } } catch (Exception e) { errMsg = e.Message; Stop(); return; } IsRuning = true; }
public void Start(out string errMsg) { // 子服务启动失败,应该不影响其他子服务 errMsg = ""; try { // Pump-OPC通信子服务 if (Config.configInfo.confSonOPCPumpDataService != null && Config.configInfo.confSonOPCPumpDataService.IsNeedRun) { opcPumpService = new OPCPumpService(Config.configInfo.confSonOPCPumpDataService); opcPumpService.Start(out errMsg); if (opcPumpService.IsRuning) { TraceManagerForOPC.AppendInfo("Pump-OPC通信子服务已经启动"); } else { errMsg = "Pump-OPC通信子服务启动失败:" + errMsg; TraceManagerForOPC.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("Pump-OPC通信子服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // Scada-OPC通信子服务 if (Config.configInfo.confSonOPCScadaDataService != null && Config.configInfo.confSonOPCScadaDataService.IsNeedRun) { opcScadaService = new OPCScadaService(Config.configInfo.confSonOPCScadaDataService); opcScadaService.Start(out errMsg); if (opcScadaService.IsRuning) { TraceManagerForOPC.AppendInfo("Scada-OPC通信子服务已经启动"); } else { errMsg = "Scada-OPC通信子服务启动失败:" + errMsg; TraceManagerForOPC.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("Scada-OPC通信子服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 二供WEB-pump通信子服务 if (Config.configInfo.confSonWebPandaPumpDataService != null && Config.configInfo.confSonWebPandaPumpDataService.IsNeedRun) { webPandaPumpService = new WEBPandaPumpService(Config.configInfo.confSonWebPandaPumpDataService); webPandaPumpService.Start(out errMsg); if (webPandaPumpService.IsRuning) { TraceManagerForWeb.AppendInfo("二供WEB通信子服务已经启动"); } else { errMsg = "二供WEB通信子服务启动失败:" + errMsg; TraceManagerForWeb.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("二供WEB通信子服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // WEB-pump-Scada 通信子服务 if (Config.configInfo.confSonWebPandaPumpScadaDataService != null && Config.configInfo.confSonWebPandaPumpScadaDataService.IsNeedRun) { webPandaPumpScadaService = new WEBPandaPumpSCADAService(Config.configInfo.confSonWebPandaPumpScadaDataService); webPandaPumpScadaService.Start(out errMsg); if (webPandaPumpScadaService.IsRuning) { TraceManagerForWeb.AppendInfo("WEB-pandaPump_Scada 通信子服务已经启动"); } else { errMsg = "WEB-pandaPump_Scada 通信子服务启动失败:" + errMsg; TraceManagerForWeb.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("WEB-pandaPump_Scada 通信子服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // SACADA—WEB-监测点通信子服务 if (Config.configInfo.confSonWebPandaYLDataService != null && Config.configInfo.confSonWebPandaYLDataService.IsNeedRun) { webPandaYLScadaService = new WEBPandaYLSacdaService(Config.configInfo.confSonWebPandaYLDataService); webPandaYLScadaService.Start(out errMsg); if (webPandaYLScadaService.IsRuning) { TraceManagerForWeb.AppendInfo("SACADA—WEB-监测点通信子服务已经启动"); } else { errMsg = "SACADA—WEB-监测点通信子服务启动失败:" + errMsg; TraceManagerForWeb.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("SACADA—WEB-监测点通信子服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // SACADA—WEB-综合测点通信子服务 if (Config.configInfo.confSonWebPandaZHCDDataService != null && Config.configInfo.confSonWebPandaZHCDDataService.IsNeedRun) { webPandaZHCDScadaServcice = new WEBPandaZHCDSacdaService(Config.configInfo.confSonWebPandaZHCDDataService); webPandaZHCDScadaServcice.Start(out errMsg); if (webPandaZHCDScadaServcice.IsRuning) { TraceManagerForWeb.AppendInfo("SACADA—WEB-综合测点通信子服务已经启动"); } else { errMsg = "SACADA—WEB-综合测点通信子服务启动失败:" + errMsg; TraceManagerForWeb.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("SACADA—WEB-综合测点通信子服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 二供报警服务 if (Config.configInfo.confSonCityIoTPumpAlarm != null && Config.configInfo.confSonCityIoTPumpAlarm.IsNeedRun) { pumpAlarmService = new PumpAlarmService(Config.configInfo.confSonCityIoTPumpAlarm); pumpAlarmService.Start(out errMsg); if (pumpAlarmService.IsRuning) { TraceManagerForPumpAlarm.AppendInfo("二供报警服务已经启动"); } else { errMsg = "二供报警服务启动失败:" + errMsg; TraceManagerForPumpAlarm.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForPumpAlarm.AppendErrMsg("二供报警服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 历史抽稀服务 if (Config.configInfo.confSonHisVacuateService != null && Config.configInfo.confSonHisVacuateService.IsNeedRun) { hisVacuate = new HisVacuate(Config.configInfo.confSonHisVacuateService); hisVacuate.Start(out errMsg); if (hisVacuate.IsRuning) { TraceManagerForHisVacuate.AppendInfo("历史抽稀服务已经启动"); } else { errMsg = "历史抽稀服务启动失败:" + errMsg; TraceManagerForHisVacuate.AppendErrMsg(errMsg); } } } catch (Exception e) { TraceManagerForHisVacuate.AppendErrMsg("历史抽稀服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 特殊项目子服务 if (Config.configInfo.confSonProjectDataService != null && Config.configInfo.confSonProjectDataService.IsNeedRun) { if (!Config.configInfo.confSonProjectDataService.EnvIsOkay) { TraceManagerForProject.AppendErrMsg("特殊项目动态库环境配置异常:" + Config.configInfo.confSonProjectDataService.ErrMsg); } else { caseManagerInjection = Interface.GetInjection(Config.configInfo.confSonProjectDataService.DllPath); caseManagerInjection.Start(out errMsg); if (caseManagerInjection.IsRuning) { TraceManagerForProject.AppendInfo(Config.configInfo.confSonProjectDataService.ProjectName + "服务已经启动"); } else { errMsg = Config.configInfo.confSonProjectDataService.ProjectName + "服务启动失败:" + errMsg; TraceManagerForProject.AppendErrMsg(errMsg); } } } } catch (Exception e) { TraceManagerForProject.AppendErrMsg(Config.configInfo.confSonProjectDataService.ProjectName + "服务启动失败:" + e.Message + "堆栈:" + e.StackTrace); } IsRuning = true; }
private void StartTestAlive() { _testAliveExit = new AutoResetEvent(false); _taskTestAlive = new Task(() => { bool isReconnecting = false; int timeout = 100; while (!_testAliveExit.WaitOne(timeout)) // 每秒检测一次 { try { lock (_client) { if (_client.ServerState == (int)OPCServerState.OPCRunning) //状态码正常 { continue; } } } catch { } if (!isReconnecting) { _isOpcConnected = false; isReconnecting = true; TraceManagerForOPC.AppendInfo("OPCServer 离线了自动重连中..."); _client = null; lock (_tagNamedIndex) { _tagNamedIndex.Clear(); } lock (_tagClientHandleIndex) { _tagClientHandleIndex.Clear(); } lock (_tagServerHandleIndex) { _tagServerHandleIndex.Clear(); } } if (Connect(true)) { TraceManagerForOPC.AppendInfo("OPCServer 离线重连成功"); isReconnecting = false; timeout = 100; } else { // 重连失败说明服务端可能正在启动, 适当延长重连周期 timeout = 2000; } } }, TaskCreationOptions.LongRunning); _taskTestAlive.Start(); }
private bool Collect(ref List <PumpJZ> jzs, out string errMsg) { errMsg = ""; if (jzs == null) { errMsg = "无法采集空对象的机组"; return(false); } foreach (PumpJZ jz in jzs) { if (jz.opc == null || !jz.opc.IsOpcConnected) { TraceManagerForOPC.AppendWarning(jz.PName + jz.PumpJZArea + "关联的OPCServer已经离线"); jz.IsOnline = false; continue; } if (jz.points == null || jz.points.Length == 0) { TraceManagerForOPC.AppendWarning(jz.PName + jz.PumpJZArea + "没有关联对应版本的点表"); jz.IsOnline = false; continue; } // 加入离线、采集时间的点 string lastTime = DataUtil.ToDateString(DateTime.Now); Point pOnline = new Point() { dbSAddress = "FOnLine", Value = jz.IsOnline == true ? 1 : 0, State = ValueState.Success, LastTime = lastTime }; Point pTempTime = new Point() { dbSAddress = "TempTime", Value = lastTime, State = ValueState.Success, LastTime = lastTime }; // 单点采集 int errorTimes = 0; // n个失败就不采集 int okayTimes = 0; // n个成功,就在线 string errPointIDs = ""; foreach (Point point in jz.points) { // 防止采集的点多了,错误消息炸了,每个都报出来了---直接让机组离线 if (errorTimes >= Config.pumpConfig.errorTimes) { TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}-pointID列表:{2}-采集失败,已跳过该机组采集,可能原因:机组离线或者被禁用采集", jz.PName, jz.PumpJZArea, errPointIDs)); jz.IsOnline = false; break; } // 检查未通过 if (!point.CheckPumpOPC(out string err)) { point.MakeFail(point.name + err); TraceManagerForOPC.AppendWarning(point.name + "配置错误" + err); continue; } string opcItemName = OpcDaClient.GetTagName(jz.FOPCServerName, jz.FOPCDeviceName, point.offsetAddress, point.dataSourceAddress); // OPC 客户端缓存队列寻找该条目值 OpcTag tag = jz.opc.GetTagByName(opcItemName, out string er); if (tag == null) { point.MakeFail(er); TraceManagerForOPC.AppendWarning(er); // 未找到tag continue; } if (!string.IsNullOrEmpty(tag.Error)) { point.MakeFail(tag.Error); errorTimes++; errPointIDs += point.pointID.ToString() + " "; // TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}-{2}采集失败,错误原因:{3}", jz.PName, jz.PumpJZArea, point.name, point.Mess)); continue; } if (tag.Value == null) { point.MakeFail(opcItemName + "取值失败"); errorTimes++; errPointIDs += point.pointID.ToString() + " "; // TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}-{2}取值失败,错误原因:{3}", jz.PName, jz.PumpJZArea, point.name, point.Mess)); continue; } // 根据数据源获取数据 point.ReadOPCPoint(tag.Value); if (point.State == ValueState.Fail) { // TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}-{2}采集失败,取值错误:{3}", jz.PName, jz.PumpJZArea, point.name, point.Mess)); errorTimes++; errPointIDs += point.pointID.ToString() + " "; continue; } else { okayTimes++; } } // 判断是否离线 if (okayTimes >= Config.pumpConfig.okayTimes) { jz.IsOnline = true; } else { jz.IsOnline = false; } // 附加离线、时间点 if (jz.IsOnline) { pOnline.Value = 1; } else { pOnline.Value = 0; } List <Point> points = new List <Point>(); points.AddRange(new Point[] { pOnline, pTempTime }); points.AddRange(jz.points); jz.points = points.ToArray(); } return(true); }
private bool LoadCache(out List <PumpJZ> jzs, out string err) { err = ""; jzs = null; Dictionary <int, List <Point> > pointsCache = new Dictionary <int, List <Point> >(); #region 查询点表 string sqlPoints = @"select t.*,t1.数据业务地址,t1.名称 from PointAddressEntry t,PumpPointAddressDetail t1 where t.点明细ID=t1.ID and t.是否激活=1 and t.版本ID in(select distinct PointAddressID from PumpJZ x,pump x1 where PumpJZReadMode='OPC' and (x.是否删除=0 or x.是否删除 is null) and (x1.是否删除=0 or x1.是否删除 is null));"; DataTable dtPoints = DBUtil.ExecuteDataTable(sqlPoints, out string errMsg); if (!string.IsNullOrWhiteSpace(errMsg)) { err = "查询二供点表版本失败:" + errMsg; return(false); } foreach (DataRow dr in dtPoints.Rows) { int versionID = DataUtil.ToInt(dr["版本ID"]); Point point = new Point() { pointID = DataUtil.ToInt(dr["ID"]), versionID = versionID, name = DataUtil.ToString(dr["名称"]), dataSourceAddress = DataUtil.ToString(dr["数据源地址"]).Trim(), offsetAddress = DataUtil.ToString(dr["偏移地址"]), dbSAddress = DataUtil.ToString(dr["数据业务地址"]).Trim(), type = Point.ToType(DataUtil.ToString(dr["数据类型"])), isActive = DataUtil.ToInt(dr["是否激活"]), isWrite = DataUtil.ToInt(dr["是否写入"]), scale = DataUtil.ToDouble(dr["倍率"]) }; if (pointsCache.Keys.Contains(versionID)) { pointsCache[versionID].Add(point); } else { pointsCache.Add(versionID, new List <Point>() { point }); } } if (pointsCache.Keys.Count == 0) { err = "点表明细没有关于OPC的点表"; return(false); } #endregion jzs = new List <PumpJZ>(); #region 查询JZ表 string sqlJZ = @"select CONVERT(varchar(50),t.ID) as BASEID ,t.PointAddressID,t.PumpJZArea,t.FOPCDeviceName ,t.FOPCServerName,t.FPLCIP, t1.PName from PumpJZ t,Pump t1 where t.PumpId=t1.ID and (t.是否删除=0 or t.是否删除 is null) and (t1.是否删除=0 or t1.是否删除 is null) and t.PumpJZReadMode='OPC' ;"; DataTable dtJZIDs = DBUtil.ExecuteDataTable(sqlJZ, out errMsg); if (!string.IsNullOrWhiteSpace(errMsg)) { err = "查询二供机组ID列表失败:" + errMsg; return(false); } foreach (DataRow dr in dtJZIDs.Rows) { int versionID = DataUtil.ToInt(dr["PointAddressID"]); if (!pointsCache.Keys.Contains(versionID)) { TraceManagerForOPC.AppendWarning("没有点表版本ID=" + versionID.ToString() + "的点表"); continue;// 此机组不采集,其他的正常采集 } List <Point> points = pointsCache[versionID]; // 准备点表 Point[] pointsCopy = ByteUtil.DeepClone <List <Point> >(points).ToArray();// 一定要深度辅助一个副本,防止引用类型 PumpJZ jz = new PumpJZ() { ID = DataUtil.ToString(dr["BASEID"]), PointAddressID = versionID, PName = DataUtil.ToString(dr["PName"]), PumpJZArea = DataUtil.ToString(dr["PumpJZArea"]), FOPCDeviceName = DataUtil.ToString(dr["FOPCDeviceName"]), FOPCServerName = DataUtil.ToString(dr["FOPCServerName"]), points = pointsCopy }; // jz加入OPC客户端对象 jz.opc = this.opcClientManager.GetOPCClient(jz.FOPCServerName); if (jz.Check(out errMsg)) { jzs.Add(jz); } else { TraceManagerForOPC.AppendWarning("PumpJZID:" + jz.ID + "环境异常:" + errMsg); } } #endregion return(true);; }
public void Start(out string errMsg) { errMsg = ""; if (IsRuning) { return; } try { // 环境检查 if (!EnvChecker.CheckForScada(out errMsg)) { TraceManagerForOPC.AppendErrMsg("SCADA-OPC环境检查未通过:" + errMsg); return; } TraceManagerForOPC.AppendDebug("SCADA-OPC环境检查通过"); //OPC客户端管理服务打开 if (opcClientManager != null) { opcClientManager.Stop(); } opcClientManager = new OpcClient(OPCClientManagerType.Scada); opcClientManager.Start(); if (opcClientManager.IsRuning) { TraceManagerForOPC.AppendDebug("OPC客户端管理服务已经打开"); } else { TraceManagerForOPC.AppendErrMsg("OPC客户端管理服务打开失败"); Stop(); return; } // 命令消费器 if (commandCustomer != null) { commandCustomer.Stop(); } commandCustomer = new StationCommandConsumer(opcClientManager); commandCustomer.Start(); if (commandCustomer.IsRuning) { TraceManagerForOPC.AppendDebug("命令消费器已经打开"); } else { TraceManagerForOPC.AppendErrMsg("命令消费器打开失败"); Stop(); return; } // 泵房点表采集者服务 if (stationCollecter != null) { stationCollecter.Stop(); } stationCollecter = new StationCollecter(opcClientManager, commandCustomer); stationCollecter.Start(); if (stationCollecter.IsRuning) { TraceManagerForOPC.AppendDebug("点表采集管理服务已经打开"); } else { TraceManagerForOPC.AppendErrMsg("点表采集管理服务打开失败"); Stop(); return; } } catch (Exception e) { errMsg = e.Message; TraceManagerForOPC.AppendErrMsg("SCADA_OPC服务启动异常" + e.Message + "堆栈:" + e.StackTrace); Stop(); return; } IsRuning = true; }
public void Stop() { try { // 特殊项目子服务 if (this.caseManagerInjection != null) { this.caseManagerInjection.Stop(); if (this.caseManagerInjection.IsRuning) { TraceManagerForProject.AppendErrMsg(Config.configInfo.confSonProjectDataService.ProjectName + "服务停止失败"); } else { TraceManagerForProject.AppendInfo(Config.configInfo.confSonProjectDataService.ProjectName + "服务已经全部停止"); } this.caseManagerInjection = null; } } catch (Exception e) { TraceManagerForProject.AppendErrMsg(Config.configInfo.confSonProjectDataService.ProjectName + "服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 历史抽稀服务 if (this.hisVacuate != null) { this.hisVacuate.Stop(); if (this.hisVacuate.IsRuning) { TraceManagerForHisVacuate.AppendErrMsg("历史抽稀服务停止失败"); } else { TraceManagerForHisVacuate.AppendInfo("历史抽稀服务已经全部停止"); } this.hisVacuate = null; } } catch (Exception e) { TraceManagerForHisVacuate.AppendErrMsg("历史抽稀服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 二供报警服务 if (this.pumpAlarmService != null) { this.pumpAlarmService.Stop(); if (this.pumpAlarmService.IsRuning) { TraceManagerForPumpAlarm.AppendErrMsg("二供报警服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("二供报警服务已经全部停止"); } this.pumpAlarmService = null; } } catch (Exception e) { TraceManagerForPumpAlarm.AppendErrMsg("二供报警服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // SACADA—WEB-综合测点通信子服务 if (this.webPandaZHCDScadaServcice != null) { this.webPandaZHCDScadaServcice.Stop(); if (this.webPandaZHCDScadaServcice.IsRuning) { TraceManagerForWeb.AppendErrMsg("SACADA-WEB-综合测点通信子服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("SACADA—WEB-综合测点通信子服务已经全部停止"); } this.webPandaZHCDScadaServcice = null; } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("SACADA—WEB-综合测点通信子服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // SACADA—WEB-监测点通信子服务 if (this.webPandaYLScadaService != null) { this.webPandaYLScadaService.Stop(); if (this.webPandaYLScadaService.IsRuning) { TraceManagerForWeb.AppendErrMsg("SACADA—WEB-监测点通信子服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("SACADA—WEB-监测点通信子服务已经全部停止"); } this.webPandaYLScadaService = null; } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("SACADA—WEB-监测点通信子服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // WEB-pandaPump_Scada 通信子服务 if (this.webPandaPumpScadaService != null) { this.webPandaPumpScadaService.Stop(); if (this.webPandaPumpScadaService.IsRuning) { TraceManagerForWeb.AppendErrMsg("二供WEB通信子服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("二供WEB通信子服务已经全部停止"); } this.webPandaPumpScadaService = null; } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("二供WEB通信子服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // 二供WEB通信子服务 if (this.webPandaPumpService != null) { this.webPandaPumpService.Stop(); if (this.webPandaPumpService.IsRuning) { TraceManagerForWeb.AppendErrMsg("二供WEB通信子服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("二供WEB通信子服务已经全部停止"); } this.webPandaPumpService = null; } } catch (Exception e) { TraceManagerForWeb.AppendErrMsg("二供WEB通信子服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // Scada-OPC通信子服务 if (this.opcScadaService != null) { this.opcScadaService.Stop(); if (this.opcScadaService.IsRuning) { TraceManagerForOPC.AppendErrMsg("Scada-OPC通信子服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("Scada-OPC通信子服务已经全部停止"); } this.opcScadaService = null; } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("Scada-OPC通信子服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } try { // Pump-OPC通信子服务 if (this.opcPumpService != null) { this.opcPumpService.Stop(); if (this.opcPumpService.IsRuning) { TraceManagerForOPC.AppendErrMsg("Pump-OPC通信子服务停止失败"); } else { TraceManagerForPumpAlarm.AppendInfo("Pump-OPC通信子服务已经全部停止"); } this.opcPumpService = null; } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("Pump-OPC通信子服务停止失败:" + e.Message + "堆栈:" + e.StackTrace); } IsRuning = false; }
// 任务执行口--并附带超时功能 public void Excute() { ActionTimeout timeoutObj = new ActionTimeout(); try { switch (this.type) { case StationCommandType.Collect: { if (opcCommandType == OPCCommandType.Cancle) //已经在调度被标记放弃了,干要紧的任务 { return; } timeoutObj.Do = ExcuteCollect; bool bo = timeoutObj.DoWithTimeout(new TimeSpan(0, 0, 0, Config.scadaConfig.commandTimeoutSeconds)); if (bo) { TraceManagerForOPC.AppendWarning("站点定时采集任务执行超时"); GC.Collect(); } } break; case StationCommandType.Write: { timeoutObj.Do = ExcuteWrite; bool bo = timeoutObj.DoWithTimeout(new TimeSpan(0, 0, 0, Config.scadaConfig.commandTimeoutSeconds)); if (bo) { CommandManager.MakeTimeout("sensorID:" + requestCommand.sensorID + "执行写值命令超时", ref requestCommand); CommandManager.CompleteCommand(requestCommand); TraceManagerForCommand.AppendWarning(requestCommand.message); GC.Collect(); } } break; case StationCommandType.Reload: { timeoutObj.Do = ExcuteReload; bool bo = timeoutObj.DoWithTimeout(new TimeSpan(0, 0, 0, Config.scadaConfig.commandTimeoutSeconds)); if (bo) { CommandManager.MakeTimeout("执行重载站点数据命令超时", ref requestCommand); CommandManager.CompleteCommand(requestCommand); TraceManagerForCommand.AppendWarning(requestCommand.message); GC.Collect(); } } break; default: TraceManagerForOPC.AppendWarning("未知的站点OPC命令类型,无法执行"); return; } } catch (Exception e) { TraceManagerForOPC.AppendErrMsg("执行站点OPC任务失败,未知的任务类型:" + e.Message + "堆栈:" + e.StackTrace); } }
private bool Collect(ref Dictionary <int, Station> dicStations, out string errMsg) { errMsg = ""; if (dicStations == null) { errMsg = "无法采集空对象的站点组"; return(false); } foreach (int key in dicStations.Keys) { Station station = dicStations[key]; if (station.opc == null || !station.opc.IsOpcConnected) { TraceManagerForOPC.AppendWarning("StationName:" + station._StationName + "关联的OPCServer已经离线"); station.IsOnline = false; continue; } if (station.sensors == null || station.sensors.Count == 0) { TraceManagerForOPC.AppendWarning("StationName:" + station._StationName + "没有关联对应的sensor需要采集"); station.IsOnline = false; continue; } // 单点采集 int errorTimes = 0; // n个失败就不采集 int okayTimes = 0; // n个成功,就在线 string errPointIDs = ""; DateTime dt = DateTime.Now; foreach (Sensor sensor in dicStations[key].sensors) { sensor.LastTime = DataUtil.ToDateString(dt); // 防止采集的点多了,错误消息炸了,每个都报出来了---直接让机组离线 if (errorTimes >= Config.scadaConfig.errorTimes) { TraceManagerForOPC.AppendWarning(string.Format("站点名称:{0}-pointID列表:{1} 采集失败,已跳过该站点采集,可能原因:站点离线或者被禁用采集", station._StationName, errPointIDs)); station.IsOnline = false; break; } // 检查未通过 if (!sensor.CheckScadaOPC(out string err)) { sensor.MakeFail(sensor.sensorName + err); TraceManagerForOPC.AppendWarning(sensor.sensorName + "配置错误" + err); continue; } // 跳过忽略型 if (sensor.type == PointType.Ignore) { continue; } string opcItemName = OpcDaClient.GetTagName(station._FOPCServerName, station._FOPCDeviceName, sensor.offsetAddress, sensor.dataSourceAddress); // OPC 客户端缓存队列寻找该条目值 OpcTag tag = station.opc.GetTagByName(opcItemName, out string er); if (tag == null) { sensor.MakeFail(er); // 未找到tag TraceManagerForOPC.AppendErrMsg(er); // 未找到tag continue; } if (!string.IsNullOrEmpty(tag.Error)) { sensor.MakeFail(tag.Error); errorTimes++; errPointIDs += sensor.pointID.ToString() + " "; // TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}采集失败,错误原因:{2}", station._StationName, sensor.sensorName, sensor.Mess)); continue; } if (tag.Value == null) { sensor.MakeFail(opcItemName + "取值失败"); errorTimes++; errPointIDs += sensor.pointID.ToString() + " "; // TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}取值失败,错误原因:{2}", station._StationName, sensor.sensorName, sensor.Mess)); continue; } // 根据数据源获取数据 sensor.ReadOPCPoint(tag.Value); if (sensor.State == ValueState.Fail) { // TraceManagerForOPC.AppendWarning(string.Format("{0}-{1}采集失败,取值错误:{2}", station._StationName, sensor.sensorName, sensor.Mess)); errorTimes++; errPointIDs += sensor.pointID.ToString() + " "; continue; } else { okayTimes++; } } // 判断是否离线 if (okayTimes >= Config.scadaConfig.okayTimes) { station.IsOnline = true; } else { station.IsOnline = false; } AddOnLinePoint(station.IsOnline, ref station); //配置在线点就维护 } return(true); }
private bool LoadCache(out Dictionary <int, Station> dicStations, out string err) { err = ""; dicStations = new Dictionary <int, Station>(); #region 查询sensor表 string sqlSensors = @"select x.*,x1.ID pointID ,x1.* from( select t.ID stationID,t.Name StationName ,t.FOPCDeviceName ,t.FOPCServerName,t.FPLCIP, t1.ID sensorID,t1.Name sensorName,t1.PointAddressID from SCADA_Station t ,SCADA_Sensor t1 where t.ID=t1.StationID and t.ReadMode='OPC' and (t.是否删除=0 or t.是否删除 is null ) and (t1.是否删除=0 or t1.是否删除 is null )) x left join PointAddressEntry x1 on x.PointAddressID=x1.ID and x1.是否激活=1;"; DataTable dtSensors = DBUtil.ExecuteDataTable(sqlSensors, out string errMsg); if (!string.IsNullOrWhiteSpace(errMsg)) { err = "查询sensor列表失败:" + errMsg; return(false); } foreach (DataRow dr in dtSensors.Rows) { Station station = new Station() { _ID = DataUtil.ToInt(dr["stationID"]), _StationName = DataUtil.ToString(dr["StationName"]), _FOPCDeviceName = DataUtil.ToString(dr["FOPCDeviceName"]), _FOPCServerName = DataUtil.ToString(dr["FOPCServerName"]), _FPLCIP = DataUtil.ToString(dr["FPLCIP"]), sensors = new List <Sensor>() }; Sensor sensor = new Sensor() { pointID = DataUtil.ToInt(dr["pointID"]), sensorID = DataUtil.ToString(dr["sensorID"]), sensorName = DataUtil.ToString(dr["sensorName"]), _PointAddressID = DataUtil.ToInt(dr["PointAddressID"]), versionID = DataUtil.ToInt(dr["版本ID"]), dataSourceAddress = DataUtil.ToString(dr["数据源地址"]).Trim(), offsetAddress = DataUtil.ToString(dr["偏移地址"]).Trim(), type = Point.ToType(DataUtil.ToString(dr["数据类型"])), isActive = DataUtil.ToInt(dr["是否激活"]), isWrite = DataUtil.ToInt(dr["是否写入"]), scale = DataUtil.ToDouble(dr["倍率"]) }; // 站点-sensor入字典库 if (dicStations.Keys.Contains(station._ID)) { dicStations[station._ID].sensors.Add(sensor); } else { station.sensors.Add(sensor); station.opc = this.opcClientManager.GetOPCClient(station._FOPCServerName); // 将站点的OPC对象赋值 if (station.Check(out errMsg)) { dicStations.Add(station._ID, station); } else { TraceManagerForOPC.AppendWarning("StationID:" + station._ID + "环境异常:" + errMsg); } } } if (dicStations.Keys.Count == 0) { err = "站点表明细没有关于OPC的站点表"; return(false); } #endregion return(true);; }