//----------------------------------------------------------------------------- // // CommandClasses.cpp // // Singleton holding methods to create each command class object // // Copyright (c) 2010 Mal Lansell // // SOFTWARE NOTICE AND LICENSE // // This file is part of OpenZWave. // // OpenZWave is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // OpenZWave is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with OpenZWave. If not, see . // //----------------------------------------------------------------------------- #include #include "command_classes/CommandClasses.h" using namespace OpenZWave; #include "command_classes/Alarm.h" #include "command_classes/ApplicationStatus.h" #include "command_classes/Association.h" #include "command_classes/AssociationCommandConfiguration.h" #include "command_classes/BarrierOperator.h" #include "command_classes/Basic.h" #include "command_classes/BasicWindowCovering.h" #include "command_classes/Battery.h" #include "command_classes/CentralScene.h" #include "command_classes/ClimateControlSchedule.h" #include "command_classes/Clock.h" #include "command_classes/Color.h" #include "command_classes/Configuration.h" #include "command_classes/ControllerReplication.h" #include "command_classes/CRC16Encap.h" #include "command_classes/DeviceResetLocally.h" #include "command_classes/DoorLock.h" #include "command_classes/DoorLockLogging.h" #include "command_classes/EnergyProduction.h" #include "command_classes/Hail.h" #include "command_classes/Indicator.h" #include "command_classes/Language.h" #include "command_classes/Lock.h" #include "command_classes/ManufacturerSpecific.h" #include "command_classes/Meter.h" #include "command_classes/MeterPulse.h" #include "command_classes/MultiCmd.h" #include "command_classes/MultiInstance.h" #include "command_classes/MultiInstanceAssociation.h" #include "command_classes/NodeNaming.h" #include "command_classes/NoOperation.h" #include "command_classes/Powerlevel.h" #include "command_classes/Proprietary.h" #include "command_classes/Protection.h" #include "command_classes/SceneActivation.h" #include "command_classes/Security.h" #include "command_classes/SensorAlarm.h" #include "command_classes/SensorBinary.h" #include "command_classes/SensorMultilevel.h" #include "command_classes/SwitchAll.h" #include "command_classes/SwitchBinary.h" #include "command_classes/SwitchMultilevel.h" #include "command_classes/SwitchToggleBinary.h" #include "command_classes/SwitchToggleMultilevel.h" #include "command_classes/TimeParameters.h" #include "command_classes/ThermostatFanMode.h" #include "command_classes/ThermostatFanState.h" #include "command_classes/ThermostatMode.h" #include "command_classes/ThermostatOperatingState.h" #include "command_classes/ThermostatSetpoint.h" #include "command_classes/UserCode.h" #include "command_classes/Version.h" #include "command_classes/WakeUp.h" #include "command_classes/ZWavePlusInfo.h" #include "value_classes/ValueBool.h" #include "value_classes/ValueButton.h" #include "value_classes/ValueByte.h" #include "value_classes/ValueDecimal.h" #include "value_classes/ValueInt.h" #include "value_classes/ValueList.h" #include "value_classes/ValueSchedule.h" #include "value_classes/ValueShort.h" #include "value_classes/ValueString.h" #include "Manager.h" #include "Options.h" #include "Utils.h" //----------------------------------------------------------------------------- // // Constructor //----------------------------------------------------------------------------- CommandClasses::CommandClasses ( ) { memset( m_commandClassCreators, 0, sizeof(pfnCreateCommandClass_t)*256 ); memset( m_supportedCommandClasses, 0, sizeof(uint32)*8 ); } //----------------------------------------------------------------------------- // // Static method to determine whether a command class is supported //----------------------------------------------------------------------------- bool CommandClasses::IsSupported ( uint8 const _commandClassId ) { // Test the bit representing the command class return( (Get().m_supportedCommandClasses[_commandClassId>>5] & (1u<<(_commandClassId&0x1f))) != 0 ); } string CommandClasses::GetName( uint8 const _commandClassId ) { for (std::map::iterator it = Get().m_namesToIDs.begin(); it != Get().m_namesToIDs.end(); it++) { if (it->second == _commandClassId) return it->first; } return string("Unknown"); } //----------------------------------------------------------------------------- // // Static method to register a command class creator method //----------------------------------------------------------------------------- void CommandClasses::Register ( uint8 const _commandClassId, string const& _commandClassName, pfnCreateCommandClass_t _creator ) { m_commandClassCreators[_commandClassId] = _creator; // Set the bit representing the command class Get().m_supportedCommandClasses[_commandClassId>>5] |= (1u<<(_commandClassId&0x1f)); m_namesToIDs[_commandClassName] = _commandClassId; } //----------------------------------------------------------------------------- // // Create a command class object using the registered method //----------------------------------------------------------------------------- CommandClass* CommandClasses::CreateCommandClass ( uint8 const _commandClassId, uint32 const _homeId, uint8 const _nodeId ) { // Get a pointer to the required CommandClass's Create method pfnCreateCommandClass_t creator = Get().m_commandClassCreators[_commandClassId]; if( NULL == creator ) { return NULL; } // Create an instance of the command class return creator( _homeId, _nodeId ); } //----------------------------------------------------------------------------- // // Register all our implemented command classes //----------------------------------------------------------------------------- void CommandClasses::RegisterCommandClasses ( ) { CommandClasses& cc = Get(); cc.Register( Alarm::StaticGetCommandClassId(), Alarm::StaticGetCommandClassName(), Alarm::Create ); cc.Register( ApplicationStatus::StaticGetCommandClassId(), ApplicationStatus::StaticGetCommandClassName(), ApplicationStatus::Create ); cc.Register( Association::StaticGetCommandClassId(), Association::StaticGetCommandClassName(), Association::Create ); cc.Register( AssociationCommandConfiguration::StaticGetCommandClassId(), AssociationCommandConfiguration::StaticGetCommandClassName(), AssociationCommandConfiguration::Create ); cc.Register( BarrierOperator::StaticGetCommandClassId(), BarrierOperator::StaticGetCommandClassName(), BarrierOperator::Create); cc.Register( Basic::StaticGetCommandClassId(), Basic::StaticGetCommandClassName(), Basic::Create ); cc.Register( BasicWindowCovering::StaticGetCommandClassId(), BasicWindowCovering::StaticGetCommandClassName(), BasicWindowCovering::Create ); cc.Register( Battery::StaticGetCommandClassId(), Battery::StaticGetCommandClassName(), Battery::Create ); cc.Register( CentralScene::StaticGetCommandClassId(), CentralScene::StaticGetCommandClassName(), CentralScene::Create ); cc.Register( ClimateControlSchedule::StaticGetCommandClassId(), ClimateControlSchedule::StaticGetCommandClassName(), ClimateControlSchedule::Create ); cc.Register( Clock::StaticGetCommandClassId(), Clock::StaticGetCommandClassName(), Clock::Create ); cc.Register( Color::StaticGetCommandClassId(), Color::StaticGetCommandClassName(), Color::Create ); cc.Register( Configuration::StaticGetCommandClassId(), Configuration::StaticGetCommandClassName(), Configuration::Create ); cc.Register( ControllerReplication::StaticGetCommandClassId(), ControllerReplication::StaticGetCommandClassName(), ControllerReplication::Create ); cc.Register( CRC16Encap::StaticGetCommandClassId(), CRC16Encap::StaticGetCommandClassName(), CRC16Encap::Create ); cc.Register( DeviceResetLocally::StaticGetCommandClassId(), DeviceResetLocally::StaticGetCommandClassName(), DeviceResetLocally::Create ); cc.Register( DoorLock::StaticGetCommandClassId(), DoorLock::StaticGetCommandClassName(), DoorLock::Create ); cc.Register( DoorLockLogging::StaticGetCommandClassId(), DoorLockLogging::StaticGetCommandClassName(), DoorLockLogging::Create); cc.Register( EnergyProduction::StaticGetCommandClassId(), EnergyProduction::StaticGetCommandClassName(), EnergyProduction::Create ); cc.Register( Hail::StaticGetCommandClassId(), Hail::StaticGetCommandClassName(), Hail::Create ); cc.Register( Indicator::StaticGetCommandClassId(), Indicator::StaticGetCommandClassName(), Indicator::Create ); cc.Register( Language::StaticGetCommandClassId(), Language::StaticGetCommandClassName(), Language::Create ); cc.Register( Lock::StaticGetCommandClassId(), Lock::StaticGetCommandClassName(), Lock::Create ); cc.Register( ManufacturerSpecific::StaticGetCommandClassId(), ManufacturerSpecific::StaticGetCommandClassName(), ManufacturerSpecific::Create ); cc.Register( Meter::StaticGetCommandClassId(), Meter::StaticGetCommandClassName(), Meter::Create ); cc.Register( MeterPulse::StaticGetCommandClassId(), MeterPulse::StaticGetCommandClassName(), MeterPulse::Create ); cc.Register( MultiCmd::StaticGetCommandClassId(), MultiCmd::StaticGetCommandClassName(), MultiCmd::Create ); cc.Register( MultiInstance::StaticGetCommandClassId(), MultiInstance::StaticGetCommandClassName(), MultiInstance::Create ); cc.Register( MultiInstanceAssociation::StaticGetCommandClassId(), MultiInstanceAssociation::StaticGetCommandClassName(), MultiInstanceAssociation::Create ); cc.Register( NodeNaming::StaticGetCommandClassId(), NodeNaming::StaticGetCommandClassName(), NodeNaming::Create ); cc.Register( NoOperation::StaticGetCommandClassId(), NoOperation::StaticGetCommandClassName(), NoOperation::Create ); cc.Register( Powerlevel::StaticGetCommandClassId(), Powerlevel::StaticGetCommandClassName(), Powerlevel::Create ); cc.Register( Proprietary::StaticGetCommandClassId(), Proprietary::StaticGetCommandClassName(), Proprietary::Create ); cc.Register( Protection::StaticGetCommandClassId(), Protection::StaticGetCommandClassName(), Protection::Create ); cc.Register( SceneActivation::StaticGetCommandClassId(), SceneActivation::StaticGetCommandClassName(), SceneActivation::Create ); cc.Register( Security::StaticGetCommandClassId(), Security::StaticGetCommandClassName(), Security::Create); cc.Register( SensorAlarm::StaticGetCommandClassId(), SensorAlarm::StaticGetCommandClassName(), SensorAlarm::Create ); cc.Register( SensorBinary::StaticGetCommandClassId(), SensorBinary::StaticGetCommandClassName(), SensorBinary::Create ); cc.Register( SensorMultilevel::StaticGetCommandClassId(), SensorMultilevel::StaticGetCommandClassName(), SensorMultilevel::Create ); cc.Register( SwitchAll::StaticGetCommandClassId(), SwitchAll::StaticGetCommandClassName(), SwitchAll::Create ); cc.Register( SwitchBinary::StaticGetCommandClassId(), SwitchBinary::StaticGetCommandClassName(), SwitchBinary::Create ); cc.Register( SwitchMultilevel::StaticGetCommandClassId(), SwitchMultilevel::StaticGetCommandClassName(), SwitchMultilevel::Create ); cc.Register( SwitchToggleBinary::StaticGetCommandClassId(), SwitchToggleBinary::StaticGetCommandClassName(), SwitchToggleBinary::Create ); cc.Register( SwitchToggleMultilevel::StaticGetCommandClassId(), SwitchToggleMultilevel::StaticGetCommandClassName(), SwitchToggleMultilevel::Create ); cc.Register( TimeParameters::StaticGetCommandClassId(), TimeParameters::StaticGetCommandClassName(), TimeParameters::Create); cc.Register( ThermostatFanMode::StaticGetCommandClassId(), ThermostatFanMode::StaticGetCommandClassName(), ThermostatFanMode::Create ); cc.Register( ThermostatFanState::StaticGetCommandClassId(), ThermostatFanState::StaticGetCommandClassName(), ThermostatFanState::Create ); cc.Register( ThermostatMode::StaticGetCommandClassId(), ThermostatMode::StaticGetCommandClassName(), ThermostatMode::Create ); cc.Register( ThermostatOperatingState::StaticGetCommandClassId(), ThermostatOperatingState::StaticGetCommandClassName(), ThermostatOperatingState::Create ); cc.Register( ThermostatSetpoint::StaticGetCommandClassId(), ThermostatSetpoint::StaticGetCommandClassName(), ThermostatSetpoint::Create ); cc.Register( UserCode::StaticGetCommandClassId(), UserCode::StaticGetCommandClassName(), UserCode::Create ); cc.Register( Version::StaticGetCommandClassId(), Version::StaticGetCommandClassName(), Version::Create ); cc.Register( WakeUp::StaticGetCommandClassId(), WakeUp::StaticGetCommandClassName(), WakeUp::Create ); cc.Register( ZWavePlusInfo::StaticGetCommandClassId(), ZWavePlusInfo::StaticGetCommandClassName(), ZWavePlusInfo::Create ); // Now all the command classes have been registered, we can modify the // supported command classes array according to the program options. string str; Options::Get()->GetOptionAsString( "Include", &str ); if( str != "" ) { // The include list has entries, so we assume that it is a // complete list of what should be supported. // Any existing support is cleared first. memset( cc.m_supportedCommandClasses, 0, sizeof(uint32)*8 ); cc.ParseCommandClassOption( str, true ); } // Apply the excluded command class option Options::Get()->GetOptionAsString( "Exclude", &str ); if( str != "" ) { cc.ParseCommandClassOption( str, false ); } } //----------------------------------------------------------------------------- // // Parse a comma delimited list of included/excluded command classes //----------------------------------------------------------------------------- void CommandClasses::ParseCommandClassOption ( string const& _optionStr, bool const _include ) { size_t pos = 0; size_t start = 0; bool parsing = true; while( parsing ) { string ccStr; pos = _optionStr.find_first_of( ",", start ); if( string::npos == pos ) { ccStr = _optionStr.substr( start ); parsing = false; } else { ccStr = _optionStr.substr( start, pos-start ); start = pos + 1; } if( ccStr != "" ) { uint8 ccIdx = GetCommandClassId( ccStr ); if( _include ) { m_supportedCommandClasses[ccIdx>>5] |= (1u<<(ccIdx&0x1f)); } else { m_supportedCommandClasses[ccIdx>>5] &= ~(1u<<(ccIdx&0x1f)); } } } } //----------------------------------------------------------------------------- // // Convert a command class name (e.g COMMAND_CLASS_BASIC) into its 8-bit ID //----------------------------------------------------------------------------- uint8 CommandClasses::GetCommandClassId ( string const& _name ) { string upperName = ToUpper( _name ); map::iterator it = m_namesToIDs.find( upperName ); if( it != m_namesToIDs.end() ) { return it->second; } return 0xff; }