/* 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;
            }
        }
    }
}
Example #2
0
/* 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);
            }
        }
    }
}