Ejemplo n.º 1
0
 // 任务分发口
 public void ExcuteCollect()
 {
     try
     {
         if (!ExcuteCollectHandle(out string errMsg))
         {
             TraceManagerForOPC.AppendWarning("站点定时采集任务执行失败;" + errMsg);
         }
     }
     catch (Exception e)
     {
         TraceManagerForOPC.AppendErrMsg("站点定时采集任务执行失败--" + e.Message + "堆栈:" + e.StackTrace);
     }
 }
Ejemplo n.º 2
0
        // 任务执行口--并附带超时功能
        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);
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);;
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);;
        }