-
Notifications
You must be signed in to change notification settings - Fork 138
/
airpi.py
203 lines (174 loc) · 5.48 KB
/
airpi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#This file takes in inputs from a variety of sensor files, and outputs information to a variety of services
import sys
sys.dont_write_bytecode = True
import RPi.GPIO as GPIO
import ConfigParser
import time
import inspect
import os
from sys import exit
from sensors import sensor
from outputs import output
def get_subclasses(mod,cls):
for name, obj in inspect.getmembers(mod):
if hasattr(obj, "__bases__") and cls in obj.__bases__:
return obj
if not os.path.isfile('sensors.cfg'):
print "Unable to access config file: sensors.cfg"
exit(1)
sensorConfig = ConfigParser.SafeConfigParser()
sensorConfig.read('sensors.cfg')
sensorNames = sensorConfig.sections()
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) #Use BCM GPIO numbers.
sensorPlugins = []
for i in sensorNames:
try:
try:
filename = sensorConfig.get(i,"filename")
except Exception:
print("Error: no filename config option found for sensor plugin " + i)
raise
try:
enabled = sensorConfig.getboolean(i,"enabled")
except Exception:
enabled = True
#if enabled, load the plugin
if enabled:
try:
mod = __import__('sensors.'+filename,fromlist=['a']) #Why does this work?
except Exception:
print("Error: could not import sensor module " + filename)
raise
try:
sensorClass = get_subclasses(mod,sensor.Sensor)
if sensorClass == None:
raise AttributeError
except Exception:
print("Error: could not find a subclass of sensor.Sensor in module " + filename)
raise
try:
reqd = sensorClass.requiredData
except Exception:
reqd = []
try:
opt = sensorClass.optionalData
except Exception:
opt = []
pluginData = {}
class MissingField(Exception): pass
for requiredField in reqd:
if sensorConfig.has_option(i,requiredField):
pluginData[requiredField]=sensorConfig.get(i,requiredField)
else:
print "Error: Missing required field '" + requiredField + "' for sensor plugin " + i
raise MissingField
for optionalField in opt:
if sensorConfig.has_option(i,optionalField):
pluginData[optionalField]=sensorConfig.get(i,optionalField)
instClass = sensorClass(pluginData)
sensorPlugins.append(instClass)
print ("Success: Loaded sensor plugin " + i)
except Exception as e: #add specific exception for missing module
print("Error: Did not import sensor plugin " + i )
raise e
if not os.path.isfile("outputs.cfg"):
print "Unable to access config file: outputs.cfg"
outputConfig = ConfigParser.SafeConfigParser()
outputConfig.read("outputs.cfg")
outputNames = outputConfig.sections()
outputPlugins = []
for i in outputNames:
try:
try:
filename = outputConfig.get(i,"filename")
except Exception:
print("Error: no filename config option found for output plugin " + i)
raise
try:
enabled = outputConfig.getboolean(i,"enabled")
except Exception:
enabled = True
#if enabled, load the plugin
if enabled:
try:
mod = __import__('outputs.'+filename,fromlist=['a']) #Why does this work?
except Exception:
print("Error: could not import output module " + filename)
raise
try:
outputClass = get_subclasses(mod,output.Output)
if outputClass == None:
raise AttributeError
except Exception:
print("Error: could not find a subclass of output.Output in module " + filename)
raise
try:
reqd = outputClass.requiredData
except Exception:
reqd = []
try:
opt = outputClass.optionalData
except Exception:
opt = []
if outputConfig.has_option(i,"async"):
async = outputConfig.getbool(i,"async")
else:
async = False
pluginData = {}
class MissingField(Exception): pass
for requiredField in reqd:
if outputConfig.has_option(i,requiredField):
pluginData[requiredField]=outputConfig.get(i,requiredField)
else:
print "Error: Missing required field '" + requiredField + "' for output plugin " + i
raise MissingField
for optionalField in opt:
if outputConfig.has_option(i,optionalField):
pluginData[optionalField]=outputConfig.get(i,optionalField)
instClass = outputClass(pluginData)
instClass.async = async
outputPlugins.append(instClass)
print ("Success: Loaded output plugin " + i)
except Exception as e: #add specific exception for missing module
print("Error: Did not import output plugin " + i )
raise e
if not os.path.isfile("settings.cfg"):
print "Unable to access config file: settings.cfg"
mainConfig = ConfigParser.SafeConfigParser()
mainConfig.read("settings.cfg")
lastUpdated = 0
delayTime = mainConfig.getfloat("Main","uploadDelay")
redPin = mainConfig.getint("Main","redPin")
greenPin = mainConfig.getint("Main","greenPin")
GPIO.setup(redPin,GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(greenPin,GPIO.OUT,initial=GPIO.LOW)
while True:
curTime = time.time()
if (curTime-lastUpdated)>delayTime:
lastUpdated = curTime
data = []
#Collect the data from each sensor
for i in sensorPlugins:
dataDict = {}
val = i.getVal()
if val==None: #this means it has no data to upload.
continue
dataDict["value"] = i.getVal()
dataDict["unit"] = i.valUnit
dataDict["symbol"] = i.valSymbol
dataDict["name"] = i.valName
dataDict["sensor"] = i.sensorName
data.append(dataDict)
working = True
for i in outputPlugins:
working = working and i.outputData(data)
if working:
print "Uploaded successfully"
GPIO.output(greenPin,GPIO.HIGH)
else:
print "Failed to upload"
GPIO.output(redPin,GPIO.HIGH)
time.sleep(1)
GPIO.output(greenPin,GPIO.LOW)
GPIO.output(redPin,GPIO.LOW)