//-----------------------------------------------------------------------------
// <ManufacturerSpecific::HandleMsg>
// Handle a message from the Z-Wave network
//-----------------------------------------------------------------------------
bool ManufacturerSpecific::HandleMsg
(
	uint8 const* _data,
	uint32 const _length,
	uint32 const _instance	// = 1
)
{
	if( ManufacturerSpecificCmd_Report == (ManufacturerSpecificCmd)_data[0] )
	{

		// first two bytes are manufacturer id code
		uint16 manufacturerId = (((uint16)_data[1])<<8) | (uint16)_data[2];

		// next four are product type and product id
		uint16 productType = (((uint16)_data[3])<<8) | (uint16)_data[4];
		uint16 productId = (((uint16)_data[5])<<8) | (uint16)_data[6];

		if( Node* node = GetNodeUnsafe() )
		{
			// Attempt to create the config parameters
			string configPath = SetProductDetails( node, manufacturerId, productType, productId);
			if( configPath.size() > 0 )
			{
				LoadConfigXML( node, configPath );
			}

			Log::Write( LogLevel_Info, GetNodeId(), "Received manufacturer specific report from node %d: Manufacturer=%s, Product=%s",
				    GetNodeId(), node->GetManufacturerName().c_str(), node->GetProductName().c_str() );
			ClearStaticRequest( StaticRequest_Values );
			node->m_manufacturerSpecificClassReceived = true;
		}

		// Notify the watchers of the name changes
		Notification* notification = new Notification( Notification::Type_NodeNaming );
		notification->SetHomeAndNodeIds( GetHomeId(), GetNodeId() );
		GetDriver()->QueueNotification( notification );

		return true;
	}

	return false;
}
Пример #2
0
//-----------------------------------------------------------------------------
// <Group::OnGroupChanged>
// Change the group contents and notify the watchers
//-----------------------------------------------------------------------------
void Group::OnGroupChanged
(
	vector<InstanceAssociation> const& _associations
)
{
	bool notify = false;

	// If the number of associations is different, we'll save 
	// ourselves some work and clear the old set now.
	if( _associations.size() != m_associations.size() )
	{
		m_associations.clear();
		notify = true;
	}
	else
	{
		// Handle initial group creation case
		if ( _associations.size() == 0 && m_associations.size() == 0 )
		{
			notify = true;
		}
	}

	// Add the new associations. 
	uint8 oldSize = (uint8)m_associations.size();

	uint8 i;
	for( i=0; i<_associations.size(); ++i )
	{
		m_associations[_associations[i]] = AssociationCommandVec();
	}

	if( (!notify) && ( oldSize != m_associations.size() ) )
	{
		// The number of nodes in the original and new groups is the same, but
		// the number of associations has grown. There must be different nodes 
		// in the original and new sets of nodes in the group.  The easiest way
		// to sort this out is to clear the associations and add the new nodes again.
		m_associations.clear();
		for( i=0; i<_associations.size(); ++i )
		{
			m_associations[_associations[i]] = AssociationCommandVec();
		}
		notify = true;
	}

	if( notify )
	{
		// If the node supports COMMAND_CLASS_ASSOCIATION_COMMAND_CONFIGURATION, we need to request the command data.
		if( Driver* driver = Manager::Get()->GetDriver( m_homeId ) )
		{
			if( Node* node = driver->GetNodeUnsafe( m_nodeId ) )
			{
				if( AssociationCommandConfiguration* cc = static_cast<AssociationCommandConfiguration*>( node->GetCommandClass( AssociationCommandConfiguration::StaticGetCommandClassId() ) ) )
				{
					for( map<InstanceAssociation,AssociationCommandVec,classcomp>::iterator it = m_associations.begin(); it != m_associations.end(); ++it )
					{
						cc->RequestCommands( m_groupIdx, it->first.m_nodeId );
					}
				}
			}
		}

		// Send notification that the group contents have changed
		Notification* notification = new Notification( Notification::Type_Group );
		notification->SetHomeAndNodeIds( m_homeId, m_nodeId );
		notification->SetGroupIdx( m_groupIdx );
		Manager::Get()->GetDriver( m_homeId )->QueueNotification( notification ); 
		// Update routes on remote node if necessary
		bool update = false;
		Options::Get()->GetOptionAsBool( "PerformReturnRoutes", &update );
		if( update )
		{
			Driver *drv = Manager::Get()->GetDriver( m_homeId );
			if (drv)
				drv->UpdateNodeRoutes( m_nodeId );
		}
	}
}