//----------------------------------------------------------------------------- // <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; }
//----------------------------------------------------------------------------- // <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 ); } } }