public override async Task <VTQ[]> ReadDataItems(string group, IList <ReadRequest> items, Duration?timeout) { bool connected = await TryConnect(); if (!connected || connection == null) { return(GetBadVTQs(items)); } var readHelper = new ReadManager <ReadValueId, Workstation.ServiceModel.Ua.DataValue>(items, request => { NodeId node = mapId2Info[request.ID].Node ?? NodeId.Null; return(new ReadValueId { AttributeId = AttributeIds.Value, NodeId = node }); }); ReadValueId[] dataItemsToRead = readHelper.GetRefs(); try { VTQ[] result; if (dataItemsToRead.Length > 0) { var readRequest = new Workstation.ServiceModel.Ua.ReadRequest { NodesToRead = dataItemsToRead, TimestampsToReturn = TimestampsToReturn.Source, }; ReadResponse readResponse = await connection.ReadAsync(readRequest); readHelper.SetAllResults(readResponse.Results, (vv, request) => MakeVTQ(vv, request.LastValue, request.ID)); result = readHelper.values; } else { result = readHelper.values; } if (readExceptionWarning) { readExceptionWarning = false; ReturnToNormal("UAReadExcept", "ReadDataItems successful again"); } return(result); } catch (Exception exp) { Exception e = exp.GetBaseException() ?? exp; readExceptionWarning = true; LogWarn("UAReadExcept", $"Read exception: {e.Message}", details: e.ToString()); Task ignored = CloseChannel(); return(GetBadVTQs(items)); } }
public override async Task <VTQ[]> ReadDataItems(string group, IList <ReadRequest> items, Duration?timeout) { if (!await TryConnect() || connection == null) { return(GetBadVTQs(items)); } var readHelper = new ReadManager <VariableRef, VariableValue>(items, readRequest => mapId2Info[readRequest.ID].VarRef); List <VariableRef> dataItemsToRead = readHelper.GetRefsList(); try { List <VariableValue> readResponse = await connection.ReadVariablesSyncIgnoreMissing(dataItemsToRead); if (readResponse.Count == dataItemsToRead.Count) { readHelper.SetAllResults(readResponse, (vv, request) => vv.Value); return(readHelper.values); } else { var badDataItems = new List <DataItem>(); for (int i = 0; i < dataItemsToRead.Count; ++i) { VariableRef v = dataItemsToRead[i]; try { VariableValue value = readResponse.First(rr => rr.Variable == v); readHelper.SetSingleResult(i, value.Value); } catch (Exception) { // not found ReadRequest req = readHelper.GetReadRequest(i); readHelper.SetSingleResult(i, VTQ.Make(req.LastValue.V, Timestamp.Now, Quality.Bad)); DataItem dataItem = mapId2Info[req.ID].Item; badDataItems.Add(dataItem); } } string[] dataItemNamesWithAddresss = badDataItems.Select(di => di.Name + ": " + di.Address).ToArray(); string details = string.Join("; ", dataItemNamesWithAddresss); string msg = badDataItems.Count == 1 ? $"Invalid address for data item '{badDataItems[0].Name}': {badDataItems[0].Address}" : $"Invalid address for {badDataItems.Count} data items"; LogError("Invalid_Addr", msg, badDataItems.Select(di => di.ID).ToArray(), details); return(readHelper.values); } } catch (Exception exp) { Exception e = exp.GetBaseException() ?? exp; LogWarn("ReadExcept", $"Read exception: {e.Message}", details: e.ToString()); Task ignored = CloseConnection(); return(GetBadVTQs(items)); } }