update esppilight lib

content of the library is not filtered on 433mhz only
This commit is contained in:
Florian committed 2018-11-28 20:41:37 +01:00
1 parent a275e48ee1
commit 67dd7ac078
1030 files changed
+203335 -116

No files matched your search

@@ -0,0 +1,603 @@
//-----------------------------------------------------------------------------
//
// Options.h
//
// Program options read from XML files or the command line.
//
// Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
// 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 <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include <algorithm>
#include <string>
#include "Defs.h"
#include "Options.h"
#include "Utils.h"
#include "Manager.h"
#include "platform/Log.h"
#include "platform/FileOps.h"
#include "tinyxml.h"
using namespace OpenZWave;
Options* Options::s_instance = NULL;
//-----------------------------------------------------------------------------
// <Options::Create>
// Static method to create an Options object
//-----------------------------------------------------------------------------
Options* Options::Create
(
string const& _configPath,
string const& _userPath,
string const& _commandLine
)
{
if( s_instance == NULL )
{
string configPath = _configPath;
string userPath = _userPath;
// Make sure a trailing path delimiter is present
if( configPath.size() > 0 && configPath[configPath.size() - 1] != '/' )
{
configPath += "/";
}
if( userPath.size() > 0 && userPath[userPath.size() - 1] != '/' )
{
userPath += "/";
}
FileOps::Create();
if( !FileOps::FolderExists( configPath ) )
{
Log::Create( "", false, true, LogLevel_Debug, LogLevel_Debug, LogLevel_None );
/* Try some default directories */
if ( FileOps::FolderExists( "config/" ) )
{
Log::Write( LogLevel_Error, "Cannot find a path to the configuration files at %s, Using config/ instead...", configPath.c_str() );
configPath = "config/";
} else if (FileOps::FolderExists("/etc/openzwave/" ) )
{
Log::Write( LogLevel_Error, "Cannot find a path to the configuration files at %s, Using /etc/openzwave/ instead...", configPath.c_str() );
configPath = "/etc/openzwave/";
#ifdef SYSCONFDIR
} else if ( FileOps::FolderExists(SYSCONFDIR ) )
{
Log::Write( LogLevel_Error, "Cannot find a path to the configuration files at %s, Using %s instead...", configPath.c_str(), SYSCONFDIR);
configPath = SYSCONFDIR;
#endif
} else {
Log::Write( LogLevel_Error, "Cannot find a path to the configuration files at %s. Exiting...", configPath.c_str() );
exit( 1 );
}
}
FileOps::Destroy();
s_instance = new Options( configPath, userPath, _commandLine );
// Add the default options
s_instance->AddOptionString( "ConfigPath", configPath, false ); // Path to the OpenZWave config folder.
s_instance->AddOptionString( "UserPath", userPath, false ); // Path to the user's data folder.
s_instance->AddOptionBool( "Logging", true ); // Enable logging of library activity.
s_instance->AddOptionString( "LogFileName", "OZW_Log.txt", false ); // Name of the log file (can be changed via Log::SetLogFileName)
s_instance->AddOptionBool( "AppendLogFile", false ); // Append new session logs to existing log file (false = overwrite)
s_instance->AddOptionBool( "ConsoleOutput", true ); // Display log information on console (as well as save to disk)
s_instance->AddOptionInt( "SaveLogLevel", LogLevel_Detail ); // Save (to file) log messages equal to or above LogLevel_Detail
s_instance->AddOptionInt( "QueueLogLevel", LogLevel_Debug ); // Save (in RAM) log messages equal to or above LogLevel_Debug
s_instance->AddOptionInt( "DumpTriggerLevel", LogLevel_None ); // Default is to never dump RAM-stored log messages
s_instance->AddOptionBool( "Associate", true ); // Enable automatic association of the controller with group one of every device.
s_instance->AddOptionString( "Exclude", string(""), true ); // Remove support for the listed command classes.
s_instance->AddOptionString( "Include", string(""), true ); // Only handle the specified command classes. The Exclude option is ignored if anything is listed here.
s_instance->AddOptionBool( "NotifyTransactions", false ); // Notifications when transaction complete is reported.
s_instance->AddOptionString( "Interface", string(""), true ); // Identify the serial port to be accessed (TODO: change the code so more than one serial port can be specified and HID)
s_instance->AddOptionBool( "SaveConfiguration", true ); // Save the XML configuration upon driver close.
s_instance->AddOptionInt( "DriverMaxAttempts", 0);
s_instance->AddOptionInt( "PollInterval", 30000); // 30 seconds (can easily poll 30 values in this time; ~120 values is the effective limit for 30 seconds)
s_instance->AddOptionBool( "IntervalBetweenPolls", false ); // if false, try to execute the entire poll list within the PollInterval time frame
// if true, wait for PollInterval milliseconds between polls
s_instance->AddOptionBool( "SuppressValueRefresh", false ); // if true, notifications for refreshed (but unchanged) values will not be sent
s_instance->AddOptionBool( "PerformReturnRoutes", true ); // if true, return routes will be updated
s_instance->AddOptionString( "NetworkKey", string(""), false);
s_instance->AddOptionBool( "RefreshAllUserCodes", false ); // if true, during startup, we refresh all the UserCodes the device reports it supports. If False, we stop after we get the first "Available" slot (Some devices have 250+ usercode slots! - That makes our Session Stage Very Long )
s_instance->AddOptionInt( "RetryTimeout", RETRY_TIMEOUT); // How long do we wait to timeout messages sent
s_instance->AddOptionBool( "EnableSIS", true); // Automatically become a SUC if there is no SUC on the network.
s_instance->AddOptionBool( "AssumeAwake", true); // Assume Devices that Support the Wakeup CC are awake when we first query them....
s_instance->AddOptionBool( "NotifyOnDriverUnload", false); // Should we send the Node/Value Notifications on Driver Unloading - Read comments in Driver::~Driver() method about possible race conditions
}
return s_instance;
}
//-----------------------------------------------------------------------------
// <Options::Destroy>
// Static method to destroy an Options object
//-----------------------------------------------------------------------------
bool Options::Destroy
(
)
{
if( Manager::Get() )
{
// Cannot delete Options because Manager object still exists
assert(0);
return false;
}
delete s_instance;
s_instance = NULL;
return true;
}
//-----------------------------------------------------------------------------
// <Options::Options>
// Constructor
//-----------------------------------------------------------------------------
Options::Options
(
string const& _configPath,
string const& _userPath,
string const& _commandLine
):
m_xml ("options.xml"),
m_commandLine( _commandLine ),
m_SystemPath (_configPath),
m_LocalPath (_userPath),
m_locked( false )
{
}
//-----------------------------------------------------------------------------
// <Options::~Options>
// Destructor
//-----------------------------------------------------------------------------
Options::~Options
(
)
{
// Clear the options map
while( !m_options.empty() )
{
map<string,Option*>::iterator it = m_options.begin();
delete it->second;
m_options.erase( it );
}
}
//-----------------------------------------------------------------------------
// <Options::AddOptionBool>
// Add a boolean option.
//-----------------------------------------------------------------------------
bool Options::AddOptionBool
(
string const& _name,
bool const _value
)
{
// get (or create) option
Option* option = AddOption( _name );
if (option == NULL) return false;
// set unique option members
option->m_type = Options::OptionType_Bool;
option->m_valueBool = _value;
// save in m_options map
string lowerName = ToLower( _name );
m_options[lowerName] = option;
return true;
}
//-----------------------------------------------------------------------------
// <Options::AddOptionInt>
// Add an integer option.
//-----------------------------------------------------------------------------
bool Options::AddOptionInt
(
string const& _name,
int32 const _value
)
{
// get (or create) option
Option* option = AddOption( _name );
if (option == NULL) return false;
// set unique option members
option->m_type = Options::OptionType_Int;
option->m_valueInt = _value;
// save in m_options map
string lowerName = ToLower( _name );
m_options[lowerName] = option;
return true;
}
//-----------------------------------------------------------------------------
// <Options::AddOptionString>
// Add a string option.
//-----------------------------------------------------------------------------
bool Options::AddOptionString
(
string const& _name,
string const& _value,
bool const _append
)
{
// get (or create) option
Option* option = AddOption( _name );
if (option == NULL) return false;
// set unique option members
option->m_type = Options::OptionType_String;
option->m_valueString = _value;
option->m_append = _append;
// save in m_options map
string lowerName = ToLower( _name );
m_options[lowerName] = option;
return true;
}
//-----------------------------------------------------------------------------
// <Options::GetOptionAsBool>
// Get the value of a boolean option.
//-----------------------------------------------------------------------------
bool Options::GetOptionAsBool
(
string const& _name,
bool* o_value
)
{
Option* option = Find( _name );
if( o_value && option && ( OptionType_Bool == option->m_type ) )
{
*o_value = option->m_valueBool;
return true;
}
Log::Write( LogLevel_Warning, "Specified option [%s] was not found.", _name.c_str() );
return false;
}
//-----------------------------------------------------------------------------
// <Options::GetOptionAsInt>
// Get the value of an integer option.
//-----------------------------------------------------------------------------
bool Options::GetOptionAsInt
(
string const& _name,
int32* o_value
)
{
Option* option = Find( _name );
if( o_value && option && ( OptionType_Int == option->m_type ) )
{
*o_value = option->m_valueInt;
return true;
}
Log::Write( LogLevel_Warning, "Specified option [%s] was not found.", _name.c_str() );
return false;
}
//-----------------------------------------------------------------------------
// <Options::GetOptionAsString>
// Get the value of a string option.
//-----------------------------------------------------------------------------
bool Options::GetOptionAsString
(
string const& _name,
string* o_value
)
{
Option* option = Find( _name );
if( o_value && option && ( OptionType_String == option->m_type ) )
{
*o_value = option->m_valueString;
return true;
}
Log::Write( LogLevel_Warning, "Specified option [%s] was not found.", _name.c_str() );
return false;
}
//-----------------------------------------------------------------------------
// <Options::GetOptionType>
// Get the type of value stored in an option.
//-----------------------------------------------------------------------------
Options::OptionType Options::GetOptionType
(
string const& _name
)
{
Option* option = Find( _name );
if( option )
{
return option->m_type;
}
// Option not found
Log::Write( LogLevel_Warning, "Specified option [%s] was not found.", _name.c_str() );
return OptionType_Invalid;
}
//-----------------------------------------------------------------------------
// <Options::Lock>
// Read all the option XMLs and Command Lines, and lock their values.
//-----------------------------------------------------------------------------
bool Options::Lock
(
)
{
if( m_locked )
{
Log::Write( LogLevel_Error, "Options are already final (locked)." );
return false;
}
ParseOptionsXML( m_SystemPath + m_xml );
ParseOptionsXML( m_LocalPath + m_xml);
ParseOptionsString( m_commandLine );
m_locked = true;
return true;
}
//-----------------------------------------------------------------------------
// <Options::ParseOptionsString>
// Parse a string containing program options, such as a command line
//-----------------------------------------------------------------------------
bool Options::ParseOptionsString
(
string const& _commandLine
)
{
bool res = true;
size_t pos = 0;
size_t start = 0;
while( 1 )
{
// find start of first option name
pos = _commandLine.find_first_of( "--", start );
if( string::npos == pos )
{
break;
}
start = pos + 2;
// found an option. Get the name.
string optionName;
pos = _commandLine.find( " ", start );
if( string::npos == pos )
{
optionName = _commandLine.substr( start );
start = pos;
}
else
{
optionName = _commandLine.substr( start, pos-start );
start = pos + 1;
}
// Find the matching option object
Option* option = Find( optionName );
if( option )
{
// Read the values
int numValues = 0;
bool parsing = true;
while( parsing )
{
string value;
size_t back = start;
pos = _commandLine.find( " ", start );
if( string::npos == pos )
{
// Last value in string
value = _commandLine.substr( start );
parsing = false;
start = pos;
}
else
{
value = _commandLine.substr( start, pos-start );
start = pos+1;
}
if( !value.compare( 0, 2, "--" ) )
{
// Value is actually the next option.
if( !numValues )
{
// No values were read for this option
// This is ok only for bool options, where we assume no value means "true".
if( OptionType_Bool == option->m_type )
{
option->m_valueBool = true;
}
else
{
res = false;
}
}
start = back; // back up to the beginning of the next option
break;
}
else if( value.size() > 0 )
{
// Set the value
option->SetValueFromString( value );
numValues++;
}
}
}
}
return res;
}
//-----------------------------------------------------------------------------
// <Options::ParseOptionsXML>
// Parse an XML file containing program options
//-----------------------------------------------------------------------------
bool Options::ParseOptionsXML
(
string const& _filename
)
{
TiXmlDocument doc;
if( !doc.LoadFile( _filename.c_str(), TIXML_ENCODING_UTF8 ) )
{
Log::Write(LogLevel_Warning, "Failed to Parse %s: %s", _filename.c_str(), doc.ErrorDesc());
return false;
}
Log::Write(LogLevel_Info, "Reading %s for Options", _filename.c_str());
TiXmlElement const* optionsElement = doc.RootElement();
// Read the options
TiXmlElement const* optionElement = optionsElement->FirstChildElement();
while( optionElement )
{
char const* str = optionElement->Value();
if( str && !strcmp( str, "Option" ) )
{
char const* name = optionElement->Attribute( "name" );
if( name )
{
Option* option = Find( name );
if( option )
{
char const* value = optionElement->Attribute( "value" );
if( value )
{
// Set the value
option->SetValueFromString( value );
}
}
}
}
optionElement = optionElement->NextSiblingElement();
}
return true;
}
//-----------------------------------------------------------------------------
// <Options::AddOption>
// General setup for adding a specific option
//-----------------------------------------------------------------------------
Options::Option* Options::AddOption
(
string const& _name
)
{
if( m_locked )
{
Log::Write( LogLevel_Error, "Options have been locked. No more may be added." );
return NULL;
}
// get a pointer to the option (and create a new Option if it doesn't already exist)
Option* option = Find( _name );
if( option == NULL )
{
option = new Option( _name );
}
return option;
}
//-----------------------------------------------------------------------------
// <Options::Find>
// Find an option by name
//-----------------------------------------------------------------------------
Options::Option* Options::Find
(
string const& _name
)
{
string lowername = ToLower( _name );
map<string,Option*>::iterator it = m_options.find( lowername );
if( it != m_options.end() )
{
return it->second;
}
return NULL;
}
//-----------------------------------------------------------------------------
// <Options::Option::SetValueFromString>
// Find an option by name
//-----------------------------------------------------------------------------
bool Options::Option::SetValueFromString
(
string const& _value
)
{
if( OptionType_Bool == m_type )
{
string lowerValue = ToLower( _value );
if( ( lowerValue == "true" ) || ( lowerValue == "1" ) )
{
m_valueBool = true;
return true;
}
if( ( lowerValue == "false" ) || ( lowerValue == "0" ) )
{
m_valueBool = false;
return true;
}
return false;
}
if( OptionType_Int == m_type )
{
m_valueInt = (int32)atol( _value.c_str() );
return true;
}
if( OptionType_String == m_type )
{
if( m_append && ( m_valueString.size() > 0 ) )
{
m_valueString += ( string(",") + _value );
}
else
{
m_valueString = _value;
}
return true;
}
return false;
}