/// <summary> /// 主通信流程:Step 6:根据数据更新上位机相关信息 /// </summary> protected void Update() { DateTime dt = DateTime.Now; if (DataChange != null) { HistoryData[] values = new HistoryData[_changedList.Count]; int i = 0; foreach (int index in _changedList) { ITag item = _items[index]; var itemData = item.Read();//这是从缓存Cache中读取的数据 if (item.Active) { item.Update(itemData, dt, QUALITIES.QUALITY_GOOD); } /* * 下面的语言判断是否要更新有变化的Itag: * 1.对敏感度为零的,只要有任何变化都要更新;??浮点数和零 比较大小 * 2.对于浮点数,新值的变化要超过敏感的 百分比 */ if (_deadband == 0 || (item.Address.VarType == DataType.FLOAT && (Math.Abs(itemData.Single / item.Value.Single - 1) > _deadband))) { values[i].ID = item.ID; values[i].Quality = item.Quality; values[i].Value = itemData; values[i].TimeStamp = item.TimeStamp; i++; } } foreach (DataChangeEventHandler deleg in DataChange.GetInvocationList()) //批量调用绑定在事件上面的委托 { deleg.BeginInvoke(this, new DataChangeEventArgs(1, values), null, null); //只在这个地方,才去调用绑定的事件,对那些更新周期为零的变量进行存储,存储周期随Group } } else { foreach (int index in _changedList) { ITag item = _items[index]; if (item.Active) { item.Update(item.Read(), dt, QUALITIES.QUALITY_GOOD); } } } }
protected void Update() { DateTime dt = DateTime.Now; if (DataChange != null) { HistoryData[] values = new HistoryData[_changedList.Count]; int i = 0; foreach (int index in _changedList) { ITag item = _items[index]; var itemData = item.Read(); if (item.Active) { item.Update(itemData, dt, QUALITIES.QUALITY_GOOD); } if (_deadband == 0 || (item.Address.VarType == DataType.FLOAT && (Math.Abs(itemData.Single / item.Value.Single - 1) > _deadband))) { values[i].ID = item.ID; values[i].Quality = item.Quality; values[i].Value = itemData; values[i].TimeStamp = item.TimeStamp; i++; } } foreach (DataChangeEventHandler deleg in DataChange.GetInvocationList()) { deleg.BeginInvoke(this, new DataChangeEventArgs(1, values), null, null); } } else { foreach (int index in _changedList) { ITag item = _items[index]; if (item.Active) { item.Update(item.Read(), dt, QUALITIES.QUALITY_GOOD); } } } _changedList.Clear(); }
public int BatchRead(DataSource source, bool isSync, params ITag[] itemArray) { if (itemArray == null) { return(-1); } int len = itemArray.Length; byte[] bt = new byte[4]; byte[] data = new byte[3 + len * 2]; int j = 0; data[j++] = fctHead; data[j++] = fctReadMultiple; data[j++] = source == DataSource.Cache ? (byte)0 : (byte)1; bt = BitConverter.GetBytes(itemArray.Length); data[j++] = bt[0]; data[j++] = bt[1]; data[j++] = bt[2]; data[j++] = bt[3]; for (int i = 0; i < len; i++) { ITag tag = itemArray[i]; bt = BitConverter.GetBytes(tag.ID); data[j++] = bt[0]; data[j++] = bt[1]; data[j++] = (byte)(tag.Address.DataSize >> 3); } SocketError error; _tcpSynCl.Send(data, 0, data.Length, SocketFlags.None, out error); int result = _tcpSynCl.Receive(tcpSynClBuffer, 0, tcpSynClBuffer.Length, SocketFlags.None, out error); j = 2; if (error == SocketError.Success) { DateTime time = DateTime.UtcNow; Storage value = Storage.Empty; for (int i = 0; i < len; i++) { ITag tag = itemArray[i]; switch (tag.Address.VarType) { case DataType.BOOL: value.Boolean = BitConverter.ToBoolean(tcpSynClBuffer, j++); break; case DataType.BYTE: value.Byte = tcpSynClBuffer[j++]; break; case DataType.SHORT: value.Int16 = BitConverter.ToInt16(tcpSynClBuffer, j); j += 2; break; case DataType.INT: value.Int32 = BitConverter.ToInt32(tcpSynClBuffer, j); j += 4; break; case DataType.FLOAT: value.Single = BitConverter.ToSingle(tcpSynClBuffer, j); j += 4; break; } tag.Update(value, time, QUALITIES.QUALITY_GOOD); } return(0); } else { throw new SocketException((int)error); } }
private void ReciveData(object state) { if (state == null || !_active) { return; } byte[] bytes = new byte[_tcpASynCl.ReceiveBufferSize]; int result = 0; SocketError error; do { result = _tcpASynCl.Receive(bytes, 0, bytes.Length, SocketFlags.None, out error); if (result > 5 && bytes[0] == 0xAB) { short len = BitConverter.ToInt16(bytes, 1); short count = BitConverter.ToInt16(bytes, 3); int j = 5; DateTime time = DateTime.UtcNow; Storage value = Storage.Empty; for (int i = 0; i < count; i++) { short id = BitConverter.ToInt16(bytes, j); j += 2; ITag tag = GetItemByID(id); if (tag != null) { DataType type = (DataType)bytes[j++]; switch (type) { case DataType.BOOL: value.Boolean = BitConverter.ToBoolean(bytes, j++); break; case DataType.BYTE: value.Byte = bytes[j++]; break; case DataType.SHORT: value.Int16 = BitConverter.ToInt16(bytes, j); j += 2; break; case DataType.INT: value.Int32 = BitConverter.ToInt32(bytes, j); j += 4; break; case DataType.FLOAT: value.Single = BitConverter.ToSingle(bytes, j); j += 4; break; } tag.Update(value, time, QUALITIES.QUALITY_GOOD); } else { byte type = bytes[j]; j += (type < 4 ? 2 : type < 6 ? 3 : 5); } } //Array.Clear(bytes, 0, count); } }while (result > 0); }