/// <summary> /// 读取数据 /// </summary> /// <returns>从设备读取的数据</returns> public async Task <Dictionary <string, ReturnUnit> > GetDatasAsync(MachineGetDataType getDataType) { try { var ans = new Dictionary <string, ReturnUnit>(); //检测并连接设备 if (!BaseUtility.IsConnected) { await BaseUtility.ConnectAsync(); } //如果无法连接,终止 if (!BaseUtility.IsConnected) { return(null); } //遍历每一个实际向设备获取数据的连续地址 foreach (var communicateAddress in CommunicateAddresses) { //获取数据 var datas = await BaseUtility.GetDatasAsync( AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, communicateAddress.SubAddress), (int) Math.Ceiling(communicateAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[ communicateAddress.DataType.FullName])); //如果没有数据,终止 if (datas == null || (datas.Length != 0 && datas.Length < (int) Math.Ceiling(communicateAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[ communicateAddress.DataType.FullName]))) { return(null); } foreach (var address in communicateAddress.OriginalAddresses) { //字节坐标的位置 var localPos = AddressHelper.MapProtocalCoordinateToAbstractCoordinate(address.Address, communicateAddress.Address, AddressTranslator.GetAreaByteLength(communicateAddress.Area)) + address.SubAddress * 0.125; //字节坐标的主地址位置 var localMainPos = (int)localPos; //字节坐标的子地址位置 var localSubPos = (int)((localPos - localMainPos) * 8); //根据类型选择返回结果的键是通讯标识还是地址 string key; switch (getDataType) { case MachineGetDataType.CommunicationTag: { key = address.CommunicationTag; break; } case MachineGetDataType.Address: { key = AddressFormater.FormatAddress(address.Area, address.Address, address.SubAddress); break; } case MachineGetDataType.Name: { key = address.Name; break; } default: { key = address.CommunicationTag; break; } } //如果没有数据返回空 if (datas.Length == 0) { ans.Add(key, new ReturnUnit { PlcValue = null, UnitExtend = address.UnitExtend }); } else { //将获取的数据和对应的通讯标识对应 ans.Add(key, new ReturnUnit { PlcValue = Convert.ToDouble( ValueHelper.GetInstance(BaseUtility.Endian) .GetValue(datas, ref localMainPos, ref localSubPos, address.DataType)) * address.Zoom, UnitExtend = address.UnitExtend }); } } } //如果不保持连接,断开连接 if (!KeepConnect) { BaseUtility.Disconnect(); } //返回数据 if (ans.All(p => p.Value.PlcValue == null)) { ans = null; } ErrorCount = 0; return(ans); } catch (Exception e) { Console.WriteLine(ConnectionToken + " " + e.Message); ErrorCount++; if (ErrorCount >= _maxErrorCount) { Disconnect(); } return(null); } }
public override IEnumerable <CommunicationUnit> Combine(IEnumerable <AddressUnit> addresses) { var continusAddresses = base.Combine(addresses).ToList(); var addressesGaps = new List <CommunicationUnitGap>(); CommunicationUnit preCommunicationUnit = null; foreach (var continusAddress in continusAddresses) { if (preCommunicationUnit == null) { preCommunicationUnit = continusAddress; continue; } if (continusAddress.Area == preCommunicationUnit.Area) { //计算间隔 var gap = new CommunicationUnitGap { EndUnit = continusAddress, GapNumber = (int) Math.Ceiling(AddressHelper.MapProtocalCoordinateToAbstractCoordinate( continusAddress.Address, preCommunicationUnit.Address, AddressTranslator.GetAreaByteLength(continusAddress.Area)) - preCommunicationUnit.GetCount * BigEndianValueHelper.Instance.ByteLength[ preCommunicationUnit.DataType.FullName]) }; addressesGaps.Add(gap); } preCommunicationUnit = continusAddress; } //减去间隔 var orderedGaps = addressesGaps.OrderBy(p => p.GapNumber); var jumpNumberInner = JumpNumber; foreach (var orderedGap in orderedGaps) { jumpNumberInner -= orderedGap.GapNumber; if (jumpNumberInner < 0) { break; } var nowAddress = orderedGap.EndUnit; var index = continusAddresses.IndexOf(nowAddress); index--; var preAddress = continusAddresses[index]; continusAddresses.RemoveAt(index); continusAddresses.RemoveAt(index); //合并两个已有的地址段,变为一个新的地址段 var newAddress = new CommunicationUnit { Area = nowAddress.Area, Address = preAddress.Address, GetCount = (int) (preAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[preAddress.DataType.FullName]) + orderedGap.GapNumber + (int) (nowAddress.GetCount * BigEndianValueHelper.Instance.ByteLength[nowAddress.DataType.FullName]), DataType = typeof(byte), OriginalAddresses = preAddress.OriginalAddresses.ToList().Union(nowAddress.OriginalAddresses) }; continusAddresses.Insert(index, newAddress); } return(continusAddresses); }