Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
dcdb
dcdb
Commits
d7e398c1
Commit
d7e398c1
authored
Sep 25, 2018
by
Micha Mueller
Browse files
WIP2: Simplify writing plugin configurators
parent
5272e779
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/headers/ConfiguratorTemplate.h
View file @
d7e398c1
...
...
@@ -22,11 +22,28 @@
#define STRCMP(node,str) boost::iequals(node.first,str)
//TODO how to set mqttsuffix? (_mqttprefix + (mqttpart) + suffix)
#define LOOP_HEADER BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) { \
if (false) {}
#define S_BASE_ATTRIBUTES bool sensorBase(S_BASE& obj, boost::property_tree::iptree& config) override { \
LOOP_HEADER
#define S_GROUP_ATTRIBUTES bool sensorGroup(S_GROUP& obj, boost::property_tree::iptree& config) override { \
LOOP_HEADER
#define S_ENTITY_ATTRIBUTES bool sensorEntity(S_ENTITY& obj, boost::property_tree::iptree& config) override { \
LOOP_HEADER
#define ADD(name,setter) else if (boost::iequals(val.first, name)) { obj.setter(val.second.data()); }
#define END_ATTRIBUTES } return true; \
}
/*
#define CONFIG boost::property_tree::iptree& config
#define ATTRIBUTES BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) { \
if (false) {}
#define ADD(name,setter) else if (boost::iequals(val.first, name)) { sBase.setter(val.second.data()); }
#define END } return true;
*/
/**
* Non-virtual interface template for the configurators.
...
...
@@ -72,23 +89,40 @@ public:
boost
::
property_tree
::
read_info
(
cfgPath
,
cfg
);
//read global variables (if present overwrite those from global.conf)
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
globalVals
=
cfg
.
get_child_optional
(
"global"
);
if
(
globalVals
)
{
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
global
,
cfg
.
get_child
(
"global"
))
{
if
(
STRCMP
(
global
,
"mqttprefix"
))
{
_mqttPrefix
=
global
.
second
.
data
();
if
(
_mqttPrefix
[
_mqttPrefix
.
length
()
-
1
]
!=
'/'
)
{
_mqttPrefix
.
append
(
"/"
);
readGlobal
(
cfg
);
//read template stuff
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
templates
=
cfg
.
get_child_optional
(
"templates"
);
if
(
templates
)
{
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
tempVal
,
cfg
.
get_child
(
"templates"
))
{
if
(
boost
::
iequals
(
tempVal
.
first
,
_entityName
))
{
//TODO
}
else
if
(
boost
::
iequals
(
tempVal
.
first
,
_groupName
))
{
LOG
(
debug
)
<<
"Template Group
\"
"
<<
tempVal
.
second
.
data
()
<<
"
\"
"
;
if
(
!
tempVal
.
second
.
empty
())
{
SGroup
group
(
tempVal
.
second
.
data
());
if
(
readSensorGroup
(
group
,
tempVal
.
second
))
{
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
sBaseVal
,
tempVal
.
second
)
{
if
(
boost
::
iequals
(
sBaseVal
.
first
,
_baseName
))
{
SBase
*
sensor
=
new
SBase
(
sBaseVal
.
second
.
data
());
if
(
readSensorBase
(
*
sensor
,
sBaseVal
.
second
))
{
group
.
pushBackSensor
(
sensor
);
}
else
{
LOG
(
warning
)
<<
"Template sensor
\"
"
<<
group
.
getName
()
<<
"::"
<<
sBaseVal
.
second
.
data
()
<<
"
\"
has bad values! Ignoring..."
;
}
}
}
_templateSensorGroups
.
insert
(
std
::
pair
<
std
::
string
,
SGroup
>
(
group
.
getName
(),
group
));
}
else
{
LOG
(
warning
)
<<
"Template group
\"
"
<<
tempVal
.
second
.
data
()
<<
"
\"
has bad values! Ignoring..."
;
}
}
LOG
(
debug
)
<<
" Using own MQTT-Prefix "
<<
_mqttPrefix
;
}
else
if
(
STRCMP
(
global
,
"cacheInterval"
))
{
_cacheInterval
=
stoul
(
global
.
second
.
data
());
LOG
(
debug
)
<<
" Using own caching interval "
<<
_cacheInterval
<<
" [s]"
;
_cacheInterval
*=
1000
;
}
}
//else if (boost::iequals(tempVal.first, _baseName)) {//TODO allow for template sensors? even useful?}
}
}
//TODO read actual entitys/groups/bases. How to handle defaults?
//read template groups
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
tempSens
=
cfg
.
get_child_optional
(
"groupTemplates"
);
if
(
tempSens
)
{
...
...
@@ -197,6 +231,7 @@ protected:
sGroup
.
setCacheInterval
(
_cacheInterval
);
//read in values inherited from SensorGroupInterface
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
val
,
config
)
{
//TODO handle default value here?
if
(
STRCMP
(
val
,
"interval"
))
{
sGroup
.
setInterval
(
stoull
(
val
.
second
.
data
()));
}
else
if
(
STRCMP
(
val
,
"minValues"
))
{
...
...
@@ -221,6 +256,26 @@ protected:
return
sensorEntity
(
sEntity
,
config
);
}
bool
readGlobal
(
boost
::
property_tree
::
iptree
&
config
)
{
boost
::
optional
<
boost
::
property_tree
::
iptree
&>
globalVals
=
config
.
get_child_optional
(
"global"
);
if
(
globalVals
)
{
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
global
,
config
.
get_child
(
"global"
))
{
if
(
boost
::
iequals
(
global
.
first
,
"mqttprefix"
))
{
_mqttPrefix
=
global
.
second
.
data
();
if
(
_mqttPrefix
[
_mqttPrefix
.
length
()
-
1
]
!=
'/'
)
{
_mqttPrefix
.
append
(
"/"
);
}
LOG
(
debug
)
<<
" Using own MQTT-Prefix "
<<
_mqttPrefix
;
}
else
if
(
boost
::
iequals
(
global
.
first
,
"cacheInterval"
))
{
_cacheInterval
=
stoul
(
global
.
second
.
data
());
LOG
(
debug
)
<<
" Using own caching interval "
<<
_cacheInterval
<<
" [s]"
;
_cacheInterval
*=
1000
;
}
}
}
return
global
(
config
);
}
/**
* Pure virtual interface method, responsible for reading the plugin-specific
* configuration part.
...
...
@@ -269,9 +324,11 @@ protected:
virtual
bool
sensorEntity
(
SEntity
&
sEntity
,
boost
::
property_tree
::
iptree
&
config
)
=
0
;
virtual
bool
global
(
boost
::
property_tree
::
iptree
&
config
)
=
0
;
std
::
string
_entityName
;
std
::
string
_groupName
;
std
::
string
_se
nsor
Name
;
std
::
string
_
ba
seName
;
std
::
string
_cfgPath
;
std
::
string
_mqttPrefix
;
...
...
src/sensors/sysfs/SysfsConfigurator.cpp
View file @
d7e398c1
...
...
@@ -11,20 +11,6 @@
using
namespace
std
;
SysfsConfigurator
::
SysfsConfigurator
()
{
_entityName
=
"host"
;
_groupName
=
"group"
;
_sensorName
=
"sensor"
;
}
SysfsConfigurator
::~
SysfsConfigurator
()
{}
bool
SysfsConfigurator
::
Entity
(
Entity
&
entity
,
config
)
{
Add_Attribute
(
"att"
,
setter
);
Add_Attribute
(
"att2"
,
setter2
);
Group
()
}
bool
SysfsConfigurator
::
derivedReadConfig
(
boost
::
property_tree
::
iptree
&
cfg
)
{
//read one sensor at a time
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
sensor
,
cfg
.
get_child
(
"sensors"
))
{
...
...
@@ -56,58 +42,3 @@ bool SysfsConfigurator::derivedReadConfig(boost::property_tree::iptree& cfg) {
}
return
true
;
}
bool
SysfsConfigurator
::
sensorBase
(
SysfsSensorBase
&
sBase
,
CONFIG
)
{
ATTRIBUTES
ADD
(
"mqttsuffix"
,
setMqtt
)
ADD
(
"path"
,
setPath
)
ADD
(
"filter"
,
setFilter
)
END
BOOST_FOREACH
(
boost
::
property_tree
::
iptree
::
value_type
&
val
,
config
)
{
if
(
STRCMP
(
val
,
"mqttsuffix"
))
{
sBase
.
setMqtt
(
_mqttPrefix
+
val
.
second
.
data
());
}
else
if
(
STRCMP
(
val
,
(
"path"
)))
{
sBase
.
setPath
(
val
.
second
.
data
());
}
else
if
(
STRCMP
(
val
,
"filter"
))
{
sBase
.
setFilter
(
true
);
string
input
=
val
.
second
.
data
();
//check if input has sed format of "s/.../.../" for substitution
regex
checkSubstitute
(
"s([^
\\\\
]{1})([
\\
S|
\\
s]*)
\\
1([
\\
S|
\\
s]*)
\\
1"
);
smatch
matchResults
;
if
(
regex_match
(
input
,
matchResults
,
checkSubstitute
))
{
//input has substitute format
LOG
(
debug
)
<<
" Init Regex with: "
<<
matchResults
[
2
].
str
();
LOG
(
debug
)
<<
" Substitution: "
<<
matchResults
[
3
].
str
();
sBase
.
setRegex
(
regex
(
matchResults
[
2
].
str
(),
regex_constants
::
extended
));
sBase
.
setSubstitution
(
matchResults
[
3
].
str
());
}
else
{
//input is only a regex
LOG
(
debug
)
<<
" Init Regex with "
<<
input
;
sBase
.
setRegex
(
regex
(
input
,
regex_constants
::
extended
));
sBase
.
setSubstitution
(
"&"
);
}
}
}
LOG
(
debug
)
<<
" MQTT : "
<<
sBase
.
getMqtt
();
LOG
(
debug
)
<<
" Path : "
<<
sBase
.
getPath
();
if
(
sBase
.
hasFilter
())
{
//regex cannot be converted back to string
LOG
(
debug
)
<<
" Using regular expression to filter data"
;
}
return
true
;
}
bool
SysfsConfigurator
::
sensorGroup
(
SysfsSensorGroup
&
sGroup
,
boost
::
property_tree
::
iptree
&
config
)
{
return
true
;
}
bool
SysfsConfiguratorsensorEntity
(
void
&
sEntity
,
boost
::
property_tree
::
iptree
&
config
)
{
return
false
;
}
src/sensors/sysfs/SysfsConfigurator.h
View file @
d7e398c1
...
...
@@ -14,18 +14,38 @@
class
SysfsConfigurator
:
public
ConfiguratorTemplate
<
SysfsSensorBase
,
SysfsSensorGroup
,
void
>
{
#define S_BASE SysfsSensorBase
#define S_GROUP SysfsSensorGroup
#define S_ENTITY void
public:
SysfsConfigurator
();
virtual
~
SysfsConfigurator
();
SysfsConfigurator
()
{
_entityName
=
"host"
;
_groupName
=
"group"
;
_sensorName
=
"sensor"
;
}
virtual
~
SysfsConfigurator
()
{}
protected:
/* Overwritten from ConfiguratorTemplate */
bool
derivedReadConfig
(
boost
::
property_tree
::
iptree
&
cfg
)
override
;
void
derivedReReadConfig
()
override
{
/* nothing to overwrite */
}
void
derivedSetGlobalSettings
(
const
pluginSettings_t
&
pluginSettings
)
override
{
/* nothing to overwrite */
}
bool
sensorBase
(
SysfsSensorBase
&
sBase
,
boost
::
property_tree
::
iptree
&
config
)
override
;
bool
sensorGroup
(
SysfsSensorGroup
&
sGroup
,
boost
::
property_tree
::
iptree
&
config
)
override
;
bool
sensorEntity
(
void
&
sEntity
,
boost
::
property_tree
::
iptree
&
config
)
override
;
bool
global
(
boost
::
property_tree
::
iptree
&
config
)
override
{
/* No plugin specific global settings */
return
true
;
}
S_BASE_ATTRIBUTES
ADD
(
"mqttsuffix"
,
setMqtt
)
ADD
(
"path"
,
setPath
)
ADD
(
"filter"
,
setFilter
)
END_ATTRIBUTES
S_GROUP_ATTRIBUTES
END_ATTRIBUTES
S_ENTITY_ATTRIBUTES
END_ATTRIBUTES
};
extern
"C"
ConfiguratorInterface
*
create
()
{
...
...
src/sensors/sysfs/SysfsSensorBase.h
View file @
d7e398c1
...
...
@@ -34,6 +34,23 @@ public:
void
setPath
(
const
std
::
string
&
path
)
{
_path
=
path
;
}
void
setFile
(
FILE
*
file
)
{
_file
=
file
;
}
void
setFilter
(
bool
filter
)
{
_filter
=
filter
;
}
void
setFilter
(
const
std
::
string
&
filter
)
{
setFilter
(
true
);
//check if input has sed format of "s/.../.../" for substitution
std
::
regex
checkSubstitute
(
"s([^
\\\\
]{1})([
\\
S|
\\
s]*)
\\
1([
\\
S|
\\
s]*)
\\
1"
);
std
::
smatch
matchResults
;
if
(
regex_match
(
filter
,
matchResults
,
checkSubstitute
))
{
//input has substitute format
setRegex
(
regex
(
matchResults
[
2
].
str
(),
std
::
regex_constants
::
extended
));
setSubstitution
(
matchResults
[
3
].
str
());
}
else
{
//input is only a regex
setRegex
(
regex
(
filter
,
std
::
regex_constants
::
extended
));
setSubstitution
(
"&"
);
}
}
void
setRegex
(
std
::
regex
regx
)
{
_regx
=
regx
;
}
void
setSubstitution
(
const
std
::
string
&
substitution
)
{
_substitution
=
substitution
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment