@@ -33,30 +33,47 @@ def load_plugin_from_file(self, filename):
33
33
plugin_name = os .path .splitext (os .path .basename (filename ))[0 ]
34
34
info ('Sections: {}' .format (config .sections ()))
35
35
for section in config .sections ():
36
- enabled = config .get (section , 'enabled' , 'true' ).lower () == 'true'
37
- if enabled :
38
- plugin = {
39
- 'filename' : filename ,
40
- 'section' : section ,
41
- 'channel' : config .get (section , 'channel' ),
42
- 'name' : config .get (section , 'name' , section ),
43
- 'module' : config .get (section , 'module' ),
44
- 'class' : config .get (section , 'class' ),
45
- 'init_args' : json .loads (config .get (section , 'init_args' , '{}' ))
46
- }
47
- folder = os .path .dirname (filename )
48
- if folder not in sys .path :
49
- sys .path .append (folder )
50
- imported_module = importlib .import_module (plugin ['module' ])
51
- device_class = getattr (imported_module , plugin ['class' ])
52
- plugin ['instance' ] = device_class (** plugin ['init_args' ])
53
- plugin ['read' ] = getattr (plugin ['instance' ], config .get (section , 'read' ))
54
- try :
55
- plugin ['write' ] = getattr (plugin ['instance' ], config .get (section , 'write' ))
56
- except :
57
- pass
58
- self .plugins [plugin_name + ':' + plugin ['channel' ]] = plugin
59
- loaded .append (section )
36
+ try :
37
+ enabled = config .get (section , 'enabled' , 'true' ).lower () == 'true'
38
+ inherit = config .get (section , 'inherit' , None )
39
+ if enabled :
40
+ plugin = {
41
+ 'filename' : filename ,
42
+ 'section' : section ,
43
+ 'channel' : config .get (section , 'channel' ),
44
+ 'name' : config .get (section , 'name' , section )
45
+ }
46
+ inherit_items = {}
47
+ if inherit in config .sections ():
48
+ if inherit == section :
49
+ raise ValueError ('Section \' {}\' cannot inherit from itself' .format (section ))
50
+ inherit_from = self .get_plugin (filename , inherit )
51
+ inherit_items = {key :value for key , value in inherit_from .items () if key not in plugin .keys ()}
52
+ plugin .update (inherit_items )
53
+ elif inherit :
54
+ raise ValueError ('Section \' {}\' cannot inherit from \' {}\' . Check spelling and section ordering.' .format (section , inherit ))
55
+ self .override_plugin_value (config , section , 'module' , plugin )
56
+ self .override_plugin_value (config , section , 'class' , plugin )
57
+ if 'init_args' not in plugin :
58
+ plugin ['init_args' ] = '{}'
59
+ self .override_plugin_value (config , section , 'init_args' , plugin )
60
+ if not inherit_items or inherit_items ['class' ] is not plugin ['class' ] or inherit_items ['init_args' ] is not plugin ['init_args' ]:
61
+ info ('Creating instance of {} for {}' .format (plugin ['class' ], plugin ['name' ]))
62
+ folder = os .path .dirname (filename )
63
+ if folder not in sys .path :
64
+ sys .path .append (folder )
65
+ imported_module = importlib .import_module (plugin ['module' ])
66
+ device_class = getattr (imported_module , plugin ['class' ])
67
+ plugin ['instance' ] = device_class (** json .loads (plugin ['init_args' ]))
68
+ self .override_plugin_value (config , section , 'read' , plugin )
69
+ try :
70
+ self .override_plugin_value (config , section , 'write' , plugin )
71
+ except :
72
+ pass
73
+ self .plugins [plugin_name + ':' + plugin ['channel' ]] = plugin
74
+ loaded .append (section )
75
+ except Exception as e :
76
+ error (e )
60
77
except Exception as e :
61
78
error (e )
62
79
info ('Loaded sections: {}' .format (loaded ))
@@ -67,12 +84,23 @@ def load_plugins(self):
67
84
for filename in fnmatch .filter (filenames , '*.plugin' ):
68
85
self .load_plugin_from_file (os .path .join (root , filename ))
69
86
87
+ def get_plugin (self , filename , section ):
88
+ """Return the plugin for the corresponding filename and section"""
89
+ return next (plugin for plugin in self .plugins .values () if plugin ['filename' ] == filename and plugin ['section' ] == section )
90
+
91
+ def override_plugin_value (self , config , section , key , plugin ):
92
+ """Override the plugin value for the specified key if it exists in the config file"""
93
+ if key not in plugin :
94
+ plugin [key ] = config .get (section , key )
95
+ else :
96
+ plugin [key ] = config .get (section , key , plugin [key ])
97
+
70
98
def get_plugin_readings (self ):
71
99
"""Return a list with current readings for all plugins"""
72
100
readings = []
73
101
for key , plugin in self .plugins .items ():
74
102
try :
75
- value = plugin ['read' ]()
103
+ value = getattr ( plugin ['instance' ], plugin [ ' read' ]) ()
76
104
value_dict = self .convert_to_dict (value )
77
105
if value_dict :
78
106
cayennemqtt .DataChannel .add (readings , cayennemqtt .DEV_SENSOR , key , name = plugin ['name' ], ** value_dict )
@@ -119,7 +147,8 @@ def write_value(self, plugin, channel, value):
119
147
info ('Write value {} to {}' .format (value , actuator ))
120
148
if actuator in self .plugins .keys ():
121
149
try :
122
- self .plugins [actuator ]['write' ](float (value ))
150
+ write_function = getattr (self .plugins [actuator ]['instance' ], self .plugins [actuator ]['write' ])
151
+ write_function (float (value ))
123
152
except :
124
153
return False
125
154
else :
0 commit comments