public override async Task <VTQ[]> ReadDataItems(string group, IList <ReadRequest> items, Duration?timeout) { int N = items.Count; if (!await TryConnect() || networkStream == null || config == null) { return(GetBadVTQs(items)); } VTQ[] vtqs = new VTQ[N]; byte[] writeBuffer = new byte[7 + 5]; // 7: Header, 5: PDU for (int i = 0; i < N; ++i) { ReadRequest request = items[i]; if (mapId2Info.ContainsKey(request.ID)) { ItemInfo item = mapId2Info[request.ID]; ModbusAddress address = item.Address; WriteUShort(writeBuffer, 0, (ushort)i); // Transaction-ID WriteUShort(writeBuffer, 2, 0); // Protocol-ID WriteUShort(writeBuffer, 4, 6); // Length writeBuffer[6] = GetModbusHeaderAddress(config, item.Item); writeBuffer[7] = GetModbusFunctionCode(config, item.Item); WriteUShort(writeBuffer, 8, (ushort)(address.Start - 1)); WriteUShort(writeBuffer, 10, address.Count); try { await networkStream.WriteAsync(writeBuffer); ushort[] words = await ReadResponse(networkStream, address.Count); vtqs[i] = ParseModbusResponse(item.Item, words, Timestamp.Now); } catch (Exception exp) { Exception e = exp.GetBaseException() ?? exp; LogWarn("ReadExcept", $"Failed to read item {item.Item.Name}: {e.Message}"); vtqs[i] = VTQ.Make(request.LastValue.V, Timestamp.Now, Quality.Bad); CloseConnection(); } } else { vtqs[i] = VTQ.Make(request.LastValue.V, Timestamp.Now, Quality.Bad); } } return(vtqs); }
protected virtual ModbusAddress GetModbusAddress(DataItem item) { bool is8Bit = item.Type == DataType.Byte || item.Type == DataType.SByte; int dimension = Math.Max(1, item.Dimension); string address = item.Address; ushort count = is8Bit ? (ushort)(dimension / 2 + dimension % 2) : (ushort)(RegisterPerType(item.Type) * dimension); if (is8Bit && (address.EndsWith('L') || address.EndsWith('H'))) { address = address.Substring(0, address.Length - 1); } ushort add = ushort.Parse(address); if (add == 0) { throw new Exception("Modbus register may not be zero. First register starts with 1."); } return(ModbusAddress.Make(add, count)); }
public ItemInfo(DataItem item, ModbusAddress address) { Item = item; Address = address; }