/* Add values for related data items UNAVAILABLE */ void Agent::disconnected (Adapter *anAdapter, vector<Device *> aDevices) { string time = getCurrentTime(GMT_UV_SEC); sLogger << LDEBUG << "Disconnected from adapter, setting all values to UNAVAILABLE"; std::vector<Device *>::iterator iter; for ( iter = aDevices.begin( ); iter != aDevices.end( ); ++iter ) { std::map<std::string, DataItem *> dataItems = ( *iter )->getDeviceDataItems( ); std::map<std::string, DataItem *>::iterator dataItemAssoc; for ( dataItemAssoc = dataItems.begin( ); dataItemAssoc != dataItems.end( ); ++dataItemAssoc ) { DataItem *dataItem = ( *dataItemAssoc ).second; if ( ( dataItem != NULL ) && ( ( dataItem->getDataSource( ) == anAdapter ) || ( anAdapter->isAutoAvailable( ) && ( dataItem->getDataSource( ) == NULL ) && ( dataItem->getType( ) == "AVAILABILITY" ) ) ) ) { const string *value = NULL; if ( dataItem->isCondition( ) ) { value = &sConditionUnavailable; } else if ( dataItem->hasConstraints( ) ) { std::vector<std::string> & values = dataItem->getConstrainedValues( ); if ( values.size( ) > 1 ) { value = &sUnavailable; } } else { value = &sUnavailable; } if ( value != NULL ) { addToBuffer(dataItem, *value, time); } } else if ( dataItem == NULL ) { sLogger << LWARN << "No data Item for " << ( *dataItemAssoc ).first; } } } }
/* Agent public methods */ Agent::Agent(const string& configXmlPath, int aBufferSize, int aMaxAssets, int aCheckpointFreq) : mPutEnabled(false), mLogStreamData(false) { try { // Load the configuration for the Agent mXmlParser = new XmlParser(); mDevices = mXmlParser->parseFile(configXmlPath); vector<Device *>::iterator device; std::set<std::string> uuids; for (device = mDevices.begin(); device != mDevices.end(); ++device) { if (uuids.count((*device)->getUuid()) > 0) throw runtime_error("Duplicate UUID: " + (*device)->getUuid()); uuids.insert((*device)->getUuid()); } } catch (runtime_error & e) { sLogger << LFATAL << "Error loading xml configuration: " + configXmlPath; sLogger << LFATAL << "Error detail: " << e.what(); cerr << e.what() << endl; throw e; } catch (exception &f) { sLogger << LFATAL << "Error loading xml configuration: " + configXmlPath; sLogger << LFATAL << "Error detail: " << f.what(); cerr << f.what() << endl; throw f; } // Grab data from configuration string time = getCurrentTime(GMT_UV_SEC); // Unique id number for agent instance mInstanceId = getCurrentTimeInSec(); // Sequence number and sliding buffer for data mSequence = 1; mSlidingBufferSize = 1 << aBufferSize; mSlidingBuffer = new sliding_buffer_kernel_1<ComponentEventPtr>(); mSlidingBuffer->set_size(aBufferSize); mCheckpointFreq = aCheckpointFreq; mCheckpointCount = (mSlidingBufferSize / aCheckpointFreq) + 1; // Asset sliding buffer mMaxAssets = aMaxAssets; // Create the checkpoints at a regular frequency mCheckpoints = new Checkpoint[mCheckpointCount]; // Mutex used for synchronized access to sliding buffer and sequence number mSequenceLock = new dlib::mutex; mAssetLock = new dlib::mutex; // Add the devices to the device map and create availability and // asset changed events if they don't exist vector<Device *>::iterator device; for (device = mDevices.begin(); device != mDevices.end(); ++device) { mDeviceMap[(*device)->getName()] = *device; // Make sure we have two device level data items: // 1. Availability // 2. AssetChanged if ((*device)->getAvailability() == NULL) { // Create availability data item and add it to the device. std::map<string,string> attrs; attrs["type"] = "AVAILABILITY"; attrs["id"] = (*device)->getId() + "_avail"; attrs["category"] = "EVENT"; DataItem *di = new DataItem(attrs); di->setComponent(*(*device)); (*device)->addDataItem(*di); (*device)->addDeviceDataItem(*di); (*device)->mAvailabilityAdded = true; } if ((*device)->getAssetChanged() == NULL) { // Create availability data item and add it to the device. std::map<string,string> attrs; attrs["type"] = "ASSET_CHANGED"; attrs["id"] = (*device)->getId() + "_asset_chg"; attrs["category"] = "EVENT"; DataItem *di = new DataItem(attrs); di->setComponent(*(*device)); (*device)->addDataItem(*di); (*device)->addDeviceDataItem(*di); } } // Reload the document for path resolution mXmlParser->loadDocument(XmlPrinter::printProbe(mInstanceId, mSlidingBufferSize, mMaxAssets, mAssets.size(), mSequence, mDevices)); /* Initialize the id mapping for the devices and set all data items to UNAVAILABLE */ for (device = mDevices.begin(); device != mDevices.end(); ++device) { const std::map<string, DataItem*> &items = (*device)->getDeviceDataItems(); std::map<string, DataItem *>::const_iterator item; for (item = items.begin(); item != items.end(); ++item) { // Check for single valued constrained data items. DataItem *d = item->second; const string *value = &sUnavailable; if (d->isCondition()) { value = &sConditionUnavailable; } else if (d->hasConstraints()) { std::vector<std::string> &values = d->getConstrainedValues(); if (values.size() == 1) value = &values[0]; } addToBuffer(d, *value, time); if (mDataItemMap.count(d->getId()) == 0) mDataItemMap[d->getId()] = d; else { sLogger << LFATAL << "Duplicate DataItem id " << d->getId() << " for device: " << (*device)->getName() << " and data item name: " << d->getName(); exit(1); } } } }