コード例 #1
0
        private void OnDataChange(int TransactionID, int NumItems, ref Array clientHandles, ref Array itemValues, ref Array qualities, ref Array timeStamps)
        {
            // 服务端异常退出后, 可能还会有残留的回调, 丢弃
            if (!_isOpcConnected)
            {
                return;
            }

            for (int i = 1; i < NumItems + 1; i++)
            {
                try
                {
                    int    clientHandle = Convert.ToInt32(clientHandles.GetValue(i));
                    OpcTag opcTag       = null;
                    lock (_tagClientHandleIndex)
                        _tagClientHandleIndex.TryGetValue(clientHandle, out opcTag);

                    if (opcTag == null)
                    {
                        continue;
                    }

                    object   value     = itemValues.GetValue(i);
                    int      quality   = Convert.ToInt32(qualities.GetValue(i));
                    DateTime timeStamp = Convert.ToDateTime(timeStamps.GetValue(i));
                    opcTag.Set(value, quality, timeStamp);
                }
                catch { }
            }
        }
コード例 #2
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);
        }
コード例 #3
0
ファイル: PumpCommand.cs プロジェクト: Jaasdsa/CityIoT
        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);
        }
コード例 #4
0
        // 枚举 OPC 服务器中所有标签
        private void BuildGroupsAndTags()
        {
            _client.OPCGroups.DefaultGroupIsActive   = true;
            _client.OPCGroups.DefaultGroupDeadband   = _defaultGroupDeadband;
            _client.OPCGroups.DefaultGroupUpdateRate = _updateRate;

            // 准备批量创建节点
            List <string> listItemIds       = new List <string>();
            List <int>    listClientHandles = new List <int>();
            int           itemHandle        = 1;
            int           itemCount         = 0;

            // 批量创建时, 数组标号从 1 开始, 0 位无用
            listItemIds.Add("");
            listClientHandles.Add(0);

            // 枚举节点
            OPCBrowser opcBrowser = _client.CreateBrowser();

            opcBrowser.ShowBranches();
            opcBrowser.ShowLeafs(true);
            foreach (object turn in opcBrowser)
            {
                string name = turn.ToString();
                if (string.IsNullOrEmpty(name))
                {
                    continue;
                }

                // 过滤系统变量
                if (name.StartsWith("_") || name.IndexOf("._") > 0)
                {
                    continue;
                }

                listItemIds.Add(name);
                listClientHandles.Add(itemHandle++);
                itemCount++;
            }

            // 创建组和节点
            _group = _client.OPCGroups.Add("RootGroup");
            Array itemIds       = listItemIds.ToArray();
            Array clientHandles = listClientHandles.ToArray();

            _group.OPCItems.AddItems(itemCount, ref itemIds, ref clientHandles, out Array serverHandles, out Array errors);

            // 创建标签
            for (int i = 1; i < itemCount + 1; i++)
            {
                string itemName     = Convert.ToString(itemIds.GetValue(i));
                int    clientHandle = Convert.ToInt32(clientHandles.GetValue(i));
                int    serverHandle = Convert.ToInt32(serverHandles.GetValue(i));

                OpcTag opcTag = new OpcTag(itemName, clientHandle, serverHandle);

                lock (_tagNamedIndex)
                    _tagNamedIndex[itemName] = opcTag;

                lock (_tagClientHandleIndex)
                    _tagClientHandleIndex[clientHandle] = opcTag;

                lock (_tagServerHandleIndex)
                    _tagServerHandleIndex[serverHandle] = opcTag;
            }

            // 启用订阅
            _group.IsSubscribed = true;
            _group.DataChange  += OnDataChange;

            // 从客户端缓存读取一次, 获取初始值
            itemCount = _group.OPCItems.Count;
            _group.SyncRead((short)OPCDataSource.OPCCache, itemCount, ref serverHandles, out Array values, out errors, out object qualities, out object timeStamps);
            for (int i = 1; i < itemCount + 1; i++)
            {
                int    serverHandle = Convert.ToInt32(serverHandles.GetValue(i));
                OpcTag opcTag       = null;

                lock (_tagServerHandleIndex)
                    _tagServerHandleIndex.TryGetValue(serverHandle, out opcTag);
                if (opcTag == null)
                {
                    continue;
                }

                object   value     = values.GetValue(i);
                int      quality   = Convert.ToInt32(((Array)qualities).GetValue(i));
                DateTime timeStamp = Convert.ToDateTime(((Array)timeStamps).GetValue(i));

                opcTag.Set(value, quality, timeStamp);
            }

            // 从设备异步读取一次
            _group.AsyncRefresh((short)OPCDataSource.OPCDevice, 1001, out int cancelId);
        }