Subversion Repositories HomeAutomation

Rev

Rev 738 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 738 Rev 748
1
###########################################################
1
###########################################################
2
#
2
#
3
# Daemon configuration
3
# Daemon configuration
4
#
4
#
5
###########################################################
5
###########################################################
6
import logging as log
6
import logging as log
7
import pickle
7
import pickle
8
import hashlib
8
import hashlib
9
import os
9
import os
10
import imp
10
import imp
11
import re
11
import re
12
from ConfigParser import ConfigParser
12
from ConfigParser import ConfigParser
13
import filters
13
import filters
14
import statespaces
14
import statespaces
15
 
15
 
16
 
16
 
17
class DynamicModuleCfg:
17
class DynamicModuleCfg:
18
    """Dynamic module manager"""
18
    """Dynamic module manager"""
19
 
19
 
20
    modSubDir = None
20
    modSubDir = None
21
    CHECKSUM_FILE = 'checksums'
21
    CHECKSUM_FILE = 'checksums'
22
    CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'
22
    CHECKSUM_SECTION = 'SHA-1_CHECKSUMS'
23
   
23
   
24
    def __init__(self, modSubDir):
24
    def __init__(self, modSubDir):
25
        self.modSubDir = modSubDir
25
        self.modSubDir = modSubDir
26
        self.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILE
26
        self.checkSumFile = modSubDir + '/' + self.CHECKSUM_FILE
27
        if not os.path.exists(self.checkSumFile):
27
        if not os.path.exists(self.checkSumFile):
28
            self.__createCsumsFile()
28
            self.__createCsumsFile()
29
   
29
   
30
    def loadModule(self, className):
30
    def loadModule(self, className):
31
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
31
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
32
        log.debug('Reading from ' + pFileName)
32
        log.debug('Reading from ' + pFileName)
33
        fp = open(pFileName, 'r')
33
        fp = open(pFileName, 'r')
34
        p = pickle.Unpickler(fp)
34
        p = pickle.Unpickler(fp)
35
        loadedMod = p.load()
35
        loadedMod = p.load()
36
        fp.close()
36
        fp.close()
37
        if not self.__verifyCheckSum(className, pFileName):
37
        if not self.__verifyCheckSum(className, pFileName):
38
            print 'Invalid checksum'
38
            print 'Invalid checksum'
39
            return None
39
            return None
40
        else:
40
        else:
41
            return loadedMod
41
            return loadedMod
42
       
42
       
43
       
43
       
44
    def loadModules(self, config = None):
44
    def loadModules(self, config = None):
45
        subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)
45
        subDirFiles = os.listdir(os.getcwd() + '/' + self.modSubDir)
46
        p = re.compile('.p$', re.IGNORECASE)
46
        p = re.compile('.p$', re.IGNORECASE)
47
        modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]
47
        modFiles = [elem for elem in subDirFiles if p.search(elem) is not None]
48
        modNames = []
48
        modNames = []
49
        for mfName in modFiles:
49
        for mfName in modFiles:
50
            modNames.append(mfName.split('.')[0])
50
            modNames.append(mfName.split('.')[0])
51
        log.debug('Found modules: ' + str(modNames))
51
        log.debug('Found modules: ' + str(modNames))
52
        myMods = {}
52
        myMods = {}
53
        for mName in modNames:
53
        for mName in modNames:
54
            classObj = self.loadModule(mName)
54
            classObj = self.loadModule(mName)
55
            if classObj is not None:
55
            if classObj is not None:
56
                myMods[mName] = classObj
56
                myMods[mName] = classObj
57
        return myMods
57
        return myMods
58
 
58
 
59
   
59
   
60
    def saveModule(self, className, classObj):
60
    def saveModule(self, className, classObj):
61
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
61
        pFileName = os.getcwd() + '/' + self.modSubDir + '/' + className + '.p'
62
        log.debug('Writing to ' + pFileName)
62
        log.debug('Writing to ' + pFileName)
63
        fp = open(pFileName, 'w')
63
        fp = open(pFileName, 'w')
64
        p = pickle.Pickler(fp)
64
        p = pickle.Pickler(fp)
65
        p.dump(classObj)
65
        p.dump(classObj)
66
        fp.close()
66
        fp.close()
67
        self.__writeCheckSum(className, pFileName)
67
        self.__writeCheckSum(className, pFileName)
68
   
68
   
69
   
69
   
70
    def __doCheckSum(self, filename):
70
    def __doCheckSum(self, filename):
71
        f = open(filename, 'r')
71
        f = open(filename, 'r')
72
        data = f.read()
72
        data = f.read()
73
        f.close()
73
        f.close()
74
        hasher = hashlib.sha1()
74
        hasher = hashlib.sha1()
75
        hasher.update(data)
75
        hasher.update(data)
76
        digest = hasher.hexdigest()
76
        digest = hasher.hexdigest()
77
        return digest
77
        return digest
78
   
78
   
79
   
79
   
80
    def __createCsumsFile(self):
80
    def __createCsumsFile(self):
81
         csumsfile = open(self.checkSumFile, 'w')
81
         csumsfile = open(self.checkSumFile, 'w')
82
         csumsfile.write('[' + self.CHECKSUM_SECTION + ']\n')
82
         csumsfile.write('[' + self.CHECKSUM_SECTION + ']\n')
83
         csumsfile.close()
83
         csumsfile.close()
84
   
84
   
85
   
85
   
86
    def __writeCheckSum(self, entryname, filename):
86
    def __writeCheckSum(self, entryname, filename):
87
        csumsfile = open(self.checkSumFile, 'r+')
87
        csumsfile = open(self.checkSumFile, 'r+')
88
        csumcfg = ConfigParser()
88
        csumcfg = ConfigParser()
89
        csumcfg.readfp(csumsfile)
89
        csumcfg.readfp(csumsfile)
90
        digest = self.__doCheckSum(filename)
90
        digest = self.__doCheckSum(filename)
91
        csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)
91
        csumcfg.set(self.CHECKSUM_SECTION, entryname, digest)
92
        csumsfile.seek(0)
92
        csumsfile.seek(0)
93
        csumcfg.write(csumsfile)
93
        csumcfg.write(csumsfile)
94
       
94
       
95
       
95
       
96
    def __verifyCheckSum(self, entryname, filename):
96
    def __verifyCheckSum(self, entryname, filename):
97
        csumsfile = open(self.checkSumFile, 'r')
97
        csumsfile = open(self.checkSumFile, 'r')
98
        csumcfg = ConfigParser()
98
        csumcfg = ConfigParser()
99
        csumcfg.readfp(csumsfile)
99
        csumcfg.readfp(csumsfile)
100
        digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)
100
        digest = csumcfg.get(self.CHECKSUM_SECTION, entryname)
101
        cur_digest = self.__doCheckSum(filename)
101
        cur_digest = self.__doCheckSum(filename)
102
        log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)
102
        log.debug('Old checksum ' + digest + '\nNew checksum: ' + cur_digest)
103
        if cur_digest == digest:
103
        if cur_digest == digest:
104
            return True
104
            return True
105
        return False
105
        return False
106
   
106
   
107
   
107
   
108
    def importModule(self, className, requiredAttributes):
108
    def importModule(self, className, requiredAttributes):
109
        """Imports a given class from the module with the same name """
109
        """Imports a given class from the module with the same name """
110
 
110
 
111
        codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'
111
        codeFile = os.getcwd() + '/' + self.modSubDir + '/' + className + '.py'
112
        mod = imp.load_source(self.modSubDir + '.' + className, codeFile)
112
        mod = imp.load_source(self.modSubDir + '.' + className, codeFile)
113
        newClass = eval('mod.' + className)()
113
        newClass = eval('mod.' + className)()
114
       
114
       
115
        for ra in requiredAttributes:
115
        for ra in requiredAttributes:
116
            if not hasattr(newClass, ra):
116
            if not hasattr(newClass, ra):
117
                print className, ': missing required symbol \"' + ra + '\"'
117
                print className, ': missing required symbol \"' + ra + '\"'
118
                return None
118
                return None
119
       
119
       
120
        self.saveModule(className, newClass)
120
        self.saveModule(className, newClass)
121
        return newClass
121
        return newClass
122
 
122
 
123
 
123
 
124
class FilterCfg:
124
class FilterCfg:
125
    """Filter resource manager"""
125
    """Filter resource manager"""
126
   
126
   
127
    REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME',
127
    REQUIRED_ATTRIBUTES = ['ASSOCIATED_SPACES', 'DESCRIPTIVE_NAME',
128
                           'attach', 'detach', 'filter']
128
                           'attach', 'detach', 'filter']
129
   
129
   
130
    dynamicModuleCfg = None
130
    dynamicModuleCfg = None
131
    FILTER_SUBDIR = 'filters'
131
    FILTER_SUBDIR = 'filters'
132
    filterModules = {}
132
    filterModules = {}
133
   
133
   
134
    def __init__(self):
134
    def __init__(self):
135
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
135
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
136
   
136
   
137
    def loadFilter(self, name):
137
    def loadFilter(self, name):
138
        newFilt = self.dynamicModuleCfg.loadModule(name)
138
        newFilt = self.dynamicModuleCfg.loadModule(name)
139
        if newFilt is not None:
139
        if newFilt is not None:
140
            filterModules[name] = newFilt
140
            self.filterModules[name] = newFilt
141
            return True
141
            return True
142
        else:
142
        else:
143
            return False
143
            return False
144
 
144
 
145
    def loadFilters(self, config = None):
145
    def loadFilters(self, config = None):
146
        self.filterModules = self.dynamicModuleCfg.loadModules()
146
        self.filterModules = self.dynamicModuleCfg.loadModules()
147
        for fM in self.filterModules:
147
        for fM in self.filterModules:
148
            log.debug(fM)
148
            log.debug(fM)
149
 
149
 
150
    def __saveFilter(self, className, classObj):
150
    def __saveFilter(self, className, classObj):
151
        self.dynamicModuleCfg.saveModule(className, classObj)
151
        self.dynamicModuleCfg.saveModule(className, classObj)
152
 
152
 
153
    def saveFilters(self):
153
    def saveFilters(self):
154
        for className in self.filterModules:
154
        for className in self.filterModules:
155
            self.__saveFilter(className, self.filterModules[className])
155
            self.__saveFilter(className, self.filterModules[className])
156
       
156
       
157
    def importFilter(self, className):
157
    def importFilter(self, className):
158
        """Imports a given filter definition """
158
        """Imports a given filter definition """
159
        classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)
159
        classObj = self.dynamicModuleCfg.importModule(className, self.REQUIRED_ATTRIBUTES)
160
        if classObj is not None:
160
        if classObj is not None:
161
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
161
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
162
            return True
162
            return True
163
        else:
163
        else:
164
            return False
164
            return False
165
       
165
       
166
 
166
 
167
class StateSpaceCfg:
167
class StateSpaceCfg:
168
    """State space resource manager"""
168
    """State space resource manager"""
169
   
169
   
170
    REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME',
170
    REQUIRED_ATTRIBUTES = ['DESCRIPTIVE_NAME', 'RELATED_SPACES'
171
                           'load', 'reset', 'run', 'unload']
171
                           'load', 'reset', 'run', 'unload']
172
   
172
   
173
    dynamicModuleCfg = None
173
    dynamicModuleCfg = None
174
    FILTER_SUBDIR = 'statespaces'
174
    FILTER_SUBDIR = 'statespaces'
175
    spaceModules = {}
175
    spaceModules = {}
176
   
176
   
177
    def __init__(self):
177
    def __init__(self):
178
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
178
        self.dynamicModuleCfg = DynamicModuleCfg(self.FILTER_SUBDIR)
179
   
179
   
180
    def loadSpace(self, name):
180
    def loadSpace(self, name):
181
        newSpace = self.dynamicModuleCfg.loadModule(name)
181
        newSpace = self.dynamicModuleCfg.loadModule(name)
182
        if newSpace is not None:
182
        if newSpace is not None:
183
            spaceModules[name] = newFilt
183
            self.spaceModules[name] = newFilt
184
            return True
184
            return True
185
        else:
185
        else:
186
            return False
186
            return False
187
 
187
 
188
    def loadSpaces(self, config = None):
188
    def loadSpaces(self, config = None):
189
        self.spaceModules = self.dynamicModuleCfg.loadModules()
189
        self.spaceModules = self.dynamicModuleCfg.loadModules()
190
        for sM in self.spaceModules:
190
        for sM in self.spaceModules:
191
            log.debug(sM)
191
            log.debug(sM)
192
 
192
 
193
    def __saveSpace(self, className, classObj):
193
    def __saveSpace(self, className, classObj):
194
        self.dynamicModuleCfg.saveModule(className, classObj)
194
        self.dynamicModuleCfg.saveModule(className, classObj)
195
 
195
 
196
    def saveSpaces(self):
196
    def saveSpaces(self):
197
        for className in self.spaceModules:
197
        for className in self.spaceModules:
198
            self.__saveSpace(className, self.spaceModules[className])
198
            self.__saveSpace(className, self.spaceModules[className])
199
   
199
   
200
    def importSpace(self, name):
200
    def importSpace(self, name):
201
        """Imports a given state space definition file """
201
        """Imports a given state space definition file """
202
        classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)
202
        classObj = self.dynamicModuleCfg.importModule(name, self.REQUIRED_ATTRIBUTES)
203
        if classObj is not None:
203
        if classObj is not None:
204
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
204
            print 'Imported: ' + classObj.DESCRIPTIVE_NAME
205
            return True
205
            return True
206
        else:
206
        else:
207
            return False
207
            return False
208
 
208
 
209
class DaemonConfig:
209
class DaemonConfig:
210
   
210
   
211
    stateSpaceCfg = None
211
    stateSpaceCfg = None
212
    filterCfg = None
212
    filterCfg = None
213
    filterChain = []
213
    filterChain = []
214
   
214
   
215
    def __init__ (self):
215
    def __init__ (self):
216
        self.filterCfg = FilterCfg()
216
        self.filterCfg = FilterCfg()
217
        self.stateSpaceCfg = StateSpaceCfg()
217
        self.stateSpaceCfg = StateSpaceCfg()
218
       
218
       
219
    def setupFilterChain(self):
219
    def setupFilterChain(self):
220
        self.filterChain = ['DefaultFilter']
220
        self.filterChain = ['DefaultFilter']
221
   
221
   
222
    def setupFilterBindings(self):
222
    def setupFilterBindings(self):
223
        for f in self.filterCfg.filterModules.values():
223
        for f in self.filterCfg.filterModules.values():
224
            assocSpaces = []
224
            assocSpaces = []
225
            for s in f.ASSOCIATED_SPACES:
225
            for s in f.ASSOCIATED_SPACES:
226
                if self.stateSpaceCfg.spaceModules.has_key(s):
226
                if self.stateSpaceCfg.spaceModules.has_key(s):
227
                    assocSpaces.append(self.stateSpaceCfg.spaceModules[s])
227
                    assocSpaces.append(self.stateSpaceCfg.spaceModules[s])
228
                else:
228
                else:
229
                    print 'WARNING: Reference to undefined state space: ' + s
229
                    print 'WARNING: Reference to undefined state space: ' + s
230
            setattr(f, '__ASSOCIATED_SPACES__', assocSpaces)
230
            setattr(f, '__ASSOCIATED_SPACES__', assocSpaces)
-
 
231
   
-
 
232
 
-
 
233
    def setupStateSpaceRelations(self):
-
 
234
        for sm in self.stateSpaceCfg.spaceModules:
-
 
235
            relatedSpaceNames = self.stateSpaceCfg.spaceModules[sm].RELATED_SPACES
-
 
236
            relatedSpaces = {}
-
 
237
            for rsname in relatedSpaceNames:
-
 
238
                relatedSpaces[rsname] = self.stateSpaceCfg.spaceModules[rsname]
-
 
239
            setattr(sm, '__RELATED_SPACES__', relatedSpaces)
231
   
240
           
232
 
241