//******************************************************************* BOOL ODevice::UpdateTags( OTagList& tags, DWORD mSec ) { if( simulate ) { sim( tags ); return TRUE; } //pCurrent->pPort->Initialize( ); // Only first call will do anything FILETIME now; CoFileTimeNow( &now ); // for each tag in the list POSITION pos = tags.GetHeadPosition(); while( pos ) { // maybe reuse a msg, instead of new/delete each time POSITION savedPos = pos; OModbusTag* pTag = tags.GetNext( pos ); // OModbusTag::TYPE range = pTag->range; // // // search for tags to group with this one // BOOL done = FALSE; // int count=1; // WORD groupSize = 1; // WORD groupStart = pTag->offset; // OModbusTag* pLastTag = pTag; // while( pos && !done) // { // OModbusTag* pNextTag = tags.GetNext( pos ); // // Can this tag be combined in a message? // if( pNextTag->offset - pLastTag->offset < ADJACENT_SPAN // && pNextTag->offset - groupStart < MAX_SPAN // && pNextTag->range == range) // { // groupSize = pNextTag->offset - groupStart + 1; // count++; // } // else // done = TRUE; // pLastTag = pNextTag; // } // // // create a packet for it // OMessage* msg = CreateReadPacket( pTag, groupSize+1 ); // // // Wait for the device's delay period? // DWORD diff = FileTimeDiff(pCurrent->lastMessage, now ); // if( diff < pCurrent->interPollDelay ) // Sleep( pCurrent->interPollDelay - diff ); // // send the message to the port and get response // m_Sent++; // msg = pCurrent->pPort->Message( msg, pCurrent->timeout ); // pCurrent->lastMessage = now; // if( msg->IsOk() == COMM_NO_ERROR ) // { // m_Rcvd++; // pCurrent->pPort->m_Rcvd++; // } // else // { // // lock // if( msg->IsOk() == TIMEOUT ) // { // m_Timeouts++; // pCurrent->pPort->m_Timeouts++; // need lock! // // // set quality for remaining tags // CSLock wait( &tagCS ); // protect data // pos = savedPos; // while( pos ) // { // pTag = tags.GetNext( pos ); // pTag->quality = OPC_QUALITY_BAD | OPC_QUALITY_COMM_FAILURE; // } // delete msg; // return FALSE; // } // else // { // m_Messages++; // pCurrent->pPort->m_Messages++; // need lock! // } // } // // // // extract the data from the packet // VARIANT value; // pos = savedPos; // while( pos && count-- ) // { // CSLock wait( &tagCS ); // protect data // pTag = tags.GetNext( pos ); // if( msg->IsOk() == COMM_NO_ERROR ) // { // switch( pTag->range ) // { // case OModbusTag::OUTPUT_BOOL: // case OModbusTag::INPUT_BOOL : // { // value.vt = VT_BOOL; // value.boolVal = msg->GetBit( pTag->offset - groupStart ); // break; // } // case OModbusTag::OUTPUT_VALUE: // case OModbusTag::INPUT_VALUE : // value.vt = pTag->nativeType; // switch( pTag->nativeType ) // { // default: // case VT_EMPTY: ASSERT( FALSE ); // case VT_I2: // value.iVal = msg->GetWord( pTag->offset - groupStart ); // break; // case VT_I4: // value.lVal = MAKELONG(msg->GetWord( pTag->offset - groupStart ), // msg->GetWord( pTag->offset - groupStart + 1 )); // if( pCurrent->wordSwap ) // value.lVal = MAKELONG(HIWORD(value.lVal),LOWORD(value.lVal)); // break; // case VT_R8: // case VT_R4: // DWORD temp = MAKELONG(msg->GetWord( pTag->offset - groupStart ), // msg->GetWord( pTag->offset - groupStart + 1 )); // if( pCurrent->wordSwap ) // temp = MAKELONG(HIWORD(temp),LOWORD(temp)); // void* pfloat = &temp; // value.fltVal = *(float*)pfloat; // break; // } // break; // default: ASSERT( FALSE ); // } // pTag->SetValue( value ); // pTag->quality = OPC_QUALITY_GOOD; // } // else // message had an error // { // pTag->quality = OPC_QUALITY_BAD | OPC_QUALITY_COMM_FAILURE; // } // pTag->timestamp = msg->timestamp; // } // delete msg; } return TRUE; }
BOOL CDeviceView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) { CDoc* pDoc = GetDocument(); if (!pDataObject->IsDataAvailable(pDoc->nIDClipFormat)) return CTreeView::OnDrop(pDataObject, dropEffect, point); // get the target device/group CTreeCtrl& tree = GetTreeCtrl(); HTREEITEM item = tree.GetDropHilightItem(); if (!item) return FALSE; OTagGroup* pGroup = (OTagGroup*)tree.GetItemData( item ); if (!pGroup) return FALSE; tree.SelectDropTarget( NULL ); // let selection be highlighted if( pGroup == pDoc->pCurrent ) // no sense copying/moving to itself return FALSE; CFile* pFile = pDataObject->GetFileData(pDoc->nIDClipFormat); if (pFile == NULL) return FALSE; CArchive ar(pFile,CArchive::load); ar.m_pDocument = pDoc; // set back-pointer in archive OTagList list; TRY { list.Serialize( ar ); } CATCH_ALL(e) { ar.Close(); delete pFile; THROW_LAST(); } END_CATCH_ALL ar.Close(); delete pFile; // insert tags into this device/group POSITION pos = list.GetHeadPosition(); while( pos ) { OModbusTag* pTag = list.GetNext( pos ); rename: // check for name conflicts POSITION searchPos = pGroup->tags.GetHeadPosition(); while( searchPos ) { OModbusTag* pTestTag = pGroup->tags.GetNext( searchPos ); if( pTag->name.CompareNoCase( pTestTag->name ) == 0 ) { // found a tag by the same name CCopyTagDlg dlg( pTag, pTestTag ); int action = dlg.DoModal(); switch( action ) { case IDC_RENAME: pTag->name = dlg.m_name; // try a new name goto rename; case IDC_OVERWRITE: *pTestTag = *pTag; // copy into current tag delete pTag; // don't insert this one goto skip; case IDC_SKIP: delete pTag; // don't insert this one goto skip; case IDCANCEL: delete pTag; // don't insert this one while( pos ) // clear out the rest of the list { delete list.GetNext( pos ); } goto cancel; } searchPos = NULL; // escape the loop } } { CSLock wait( &uiCS ); pGroup->AddTag( pTag ); pTag->pGroup = pGroup; } skip: ; } cancel: pDoc->SetModifiedFlag(); return TRUE; }
void sim( OTagList& tags ) { CSLock wait( &tagCS ); // protect data double t = GetTickCount()/6000.0; POSITION pos = tags.GetHeadPosition(); while( pos ) { OModbusTag* pTag = tags.GetNext( pos ); pTag->quality = OPC_QUALITY_GOOD; if( !pTag->active || pTag->m_IsOutput) continue; switch( pTag->value.vt ) { case VT_EMPTY: case VT_NULL: pTag->value.vt = VT_R8; pTag->value.dblVal = 0.0; break; case VT_BOOL: switch(pTag->simType) { case OModbusTag::SIN: case OModbusTag::RAMP: pTag->value.boolVal = ((int)t)&1 ? VARIANT_TRUE : VARIANT_FALSE; break; case OModbusTag::RANDOM: pTag->value.boolVal = rand()&1 ? VARIANT_TRUE : VARIANT_FALSE; break; } break; case VT_UI1: // uchar switch(pTag->simType) { case OModbusTag::SIN: pTag->value.bVal = (UCHAR)(50*sin(pi*t/10)+50); break; case OModbusTag::RAMP: pTag->value.bVal = (pTag->value.bVal+1)%100; break; case OModbusTag::RANDOM: pTag->value.bVal = rand()%100; break; } break; case VT_I2 : // short switch(pTag->simType) { case OModbusTag::SIN: pTag->value.iVal = (short)(50*sin(pi*t/10)+50); break; case OModbusTag::RAMP: pTag->value.iVal = (pTag->value.iVal+1)%100; break; case OModbusTag::RANDOM: pTag->value.iVal = rand()%100; break; } break; case VT_I4 : // long switch(pTag->simType) { case OModbusTag::SIN: pTag->value.lVal = (long)(50*sin(pi*t/10)+50); break; case OModbusTag::RAMP: pTag->value.lVal = (pTag->value.lVal+1)%100; break; case OModbusTag::RANDOM: pTag->value.lVal = rand()%100; break; } break; case VT_R4 : switch(pTag->simType) { case OModbusTag::SIN: pTag->value.fltVal = (float)sin(pi*t/10); break; case OModbusTag::RAMP: pTag->value.fltVal = (float)(long(t)%100); break; case OModbusTag::RANDOM: pTag->value.fltVal = (float)((rand()%300)/3.0); break; } break; case VT_R8 : switch(pTag->simType) { case OModbusTag::SIN: pTag->value.dblVal = sin(pi*t/10); break; case OModbusTag::RAMP: pTag->value.dblVal = (long)(t)%100; break; case OModbusTag::RANDOM: pTag->value.dblVal = (rand()%300)/3.0; break; } break; default: ASSERT( FALSE ); } CoFileTimeNow( &pTag->timestamp ); } }