forked from cbates8/CompostMonitoringSystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
276 lines (245 loc) · 10.7 KB
/
main.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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# Import all the necessary libraries
from time import *
from datetime import datetime as dt
from pickleshare import *
import adafruit_mcp3xxx.mcp3008 as MCP
from multiprocessing import Process
import shutil
import os
import urllib3
import json
import matplotlib.pyplot as plt
import numpy as np
import notecard
from periphery import I2C
# Locally imported files.
from moistureSensor import MoistureSensor
from TemperatureSensor import TemperatureSensor
def main():
# helper functions
# route: string containing one of the Ubidots routes (Temp1-3, Moisture1-3)
# value: sensor value
# timestamp: (int) unix time
def postUbi(route, value, timestamp):
try:
req = {"req": "web.post"}
req["route"] = "Ubidots: " + route
req["body"] = {"value": value, "timestamp": epoch }
rsp = card.Transaction(req)
print("Sending " + route + f" Data\nNotecard response: {rsp}\n")
return True
except:
print("error sending " + route + " data. skipping\n")
return False
# subject: string containing subject line
# message: string containing message text
# to: string containing destination email address
# sends email through notecard
# return true if succesful false otherwise
def sendEmail(subject, message, to):
try:
req = {"req": "web.post"}
req["route"] = "Email"
req["body"] = {"personalizations": [{"to": [{"email": e}]}],"from": {"email": "ucce.bin.monitoring@gmail.com"},"subject": subject,"content": [{"type": "text/plain", "value": message}]}
rsp = card.Transaction(req)
print("Sending Email\n")
print("to: " + to + "\nsubject: " + subject + "\nmessage: " + message + "\n")
print(f"Notecard response: {rsp}\n")
return True
except:
return False
# gets unix time from a server specified in notehub routes
# returns (int) unixtime if successful -1 otherwise
def getNetTime():
try:
req = {"req": "web.get"}
req["route"] = "Time"
rsp = card.Transaction(req)
print(f"Getting Time\nNotecard response: {rsp}\n")
return (rsp["body"])["unixtime"]
except:
return -1
# Declare notecard stuff
productUID = "com.gmail.ucce.bin.monitoring:compost_monitoring_system"
port = I2C("/dev/i2c-1")
card = notecard.OpenI2C(port, 0, 0)
# Declare objects.
emails = ["scamacho@scu.edu"]
tempUpperThreshold = 50
tempLowerThreshold = 49
moistureUpperThreshold = 79
moistureLowerThreshold = 80
#TODO get email and threshold values off a google sheet
thresholdFlags = [0,0,0,0,0,0] #i(0-2): temp1-3, i(3-5): moisture1-3. 1=out of threshold
waitTimeDefault = 1800 # set default report interval
waitTime = waitTimeDefault
moisture_one = MoistureSensor(MCP.P0)
moisture_two = MoistureSensor(MCP.P1)
moisture_three = MoistureSensor(MCP.P3)
temp_one = TemperatureSensor(0)
temp_two = TemperatureSensor(1)
temp_three = TemperatureSensor(2)
temp1 = []
temp2 = []
temp3 = []
moist1 = []
moist2 = []
moist3 = []
timeS = []
# Read Calibration values from CSV to correctly map new readings
print(f"Sensor\tAirVal\tWaterVal")
moisture_one.readCalibrationVals()
moisture_two.readCalibrationVals()
moisture_three.readCalibrationVals()
# Configure Notecard and confirm connection
connected = False
while(not connected):
try:
req = {"req": "hub.set"}
req["product"] = productUID
req["mode"] = "continuous"
print(f"\nNotecard config request: {json.dumps(req)}")
rsp = card.Transaction(req)
print(f"Notecard config response: {rsp}\n")
connected = True
except:
print("error connecting to internet. retrying in 1 minute\n")
time.sleep(60)
# Set day 1 used to see when a new day begins
day1 = dt.now().strftime("%d")
# Open first data collection file with appropriate date
dt_string = dt.now().strftime("D%dM%mY%YH%HM%MS%S")
file = open("/home/pi/CompostMonitoringSystem/CompostMonitoringData/" + dt_string + ".txt", "w")
while (True):
# Sets up the temperature variables.
# Records values to appropriate arrays to be used for plots
# Check if values are within threshold
temperature_one = temp_one.read_temp()
temp1.append(temperature_one)
if(not (tempUpperThreshold > temperature_one > tempLowerThreshold)):
thresholdFlags[0] = 1
temperature_two = temp_two.read_temp()
temp2.append(temperature_two)
if(not (tempUpperThreshold > temperature_two > tempLowerThreshold)):
thresholdFlags[1] = 1
temperature_three = temp_three.read_temp()
temp3.append(temperature_three)
if(not (tempUpperThreshold > temperature_three > tempLowerThreshold)):
thresholdFlags[2] = 1
current_M1_Val = moisture_one.mapSensorVals()
moist1.append(current_M1_Val)
if(not (tempUpperThreshold > current_M1_Val > tempLowerThreshold)):
thresholdFlags[3] = 1
current_M2_Val = moisture_two.mapSensorVals()
moist2.append(current_M2_Val)
if(not (tempUpperThreshold > current_M2_Val > tempLowerThreshold)):
thresholdFlags[4] = 1
current_M3_Val = moisture_three.mapSensorVals()
moist3.append(current_M3_Val)
if(not (tempUpperThreshold > current_M1_Val > tempLowerThreshold)):
thresholdFlags[5] = 1
# Stores time in seconds when values were taken in array for plotting
timeS.append(int(dt.now().strftime("%H"))*60*60+int(dt.now().strftime("%M"))*60+int(dt.now().strftime("%S")))
# Creates a dict of the current vals.
curr_data = {
'moisture_value_1': current_M1_Val,
'moisture_value_2': current_M2_Val,
'moisture_value_3': current_M3_Val,
'temp_value_1': temperature_one,
'temp_value_2': temperature_two,
'temp_value_3': temperature_three,
'time': dt_string,
}
# Sets dt_string again to be used in print statement
dt_string = dt.now().strftime("D%dM%mY%YH%HM%MS%S")
# Prints the current values.
print("Current value", current_M1_Val, current_M2_Val, current_M3_Val, '\n\tCurrent Time:', dt_string)
print("Current Temps:\n\t" + str(temperature_one) + "\n\t" + str(temperature_two) + "\n\t" + str(temperature_three) + "\n")
# Send values to the Notecard
noteSent = False
while(not noteSent):
try:
req = {"req": "note.add"}
req["file"] = "sensors.qo"
req["sync"] = True
req["body"] = {"temp1": temperature_one, "temp2": temperature_two, "temp3": temperature_three, "moisture1": current_M1_Val, "moisture2": current_M2_Val, "moisture3": current_M3_Val}
rsp = card.Transaction(req)
print(f"Notecard response: {rsp}\n")
noteSent = True
except:
print("error note not sent. retrying in 1 minute\n")
time.sleep(60)
#TODO use internet time instead of local time
epoch = time.time() * 1000
# Trigger route to send Temp1 data to Ubidots
postUbi("Temp1", temperature_one, epoch)
time.sleep(5)
# Trigger route to send Temp2 data to Ubidots
postUbi("Temp2", temperature_two, epoch)
time.sleep(5)
# Trigger route to send Temp3 data to Ubidots
postUbi("Temp3", temperature_three, epoch)
time.sleep(5)
# Trigger route to send Moisture1 data to Ubidots
postUbi("Moisture1", current_M1_Val, epoch)
time.sleep(5)
# Trigger route to send Moisture2 data to Ubidots
postUbi("Moisture2", current_M2_Val, epoch)
time.sleep(5)
# Trigger route to send Moisture3 data to Ubidots
postUbi("Moisture3", current_M3_Val, epoch)
time.sleep(5)
# Send email if values are out of threshold
if(thresholdFlags.count(1) > 0):
message = "Hi sending a different message so i dont get thrown in the bad place. sysTime: "
#TODO generate message based on sensor values
netTime = getNetTime()
message = message + str(epoch) + " netTime: " + str(netTime)
#for e in emails:
# sendEmail("Sensor values out of threshold", message, e)
#TODO make sure email are sent out no more than once every 24 hrs
# if error
# print("Connection failed. retrying in 5 minutes")
# waitTime = 300 #5 minutes
# Write collected data to text file then wait 30 minutes
str_dictionary = repr(curr_data)
file.write(str_dictionary + "\n")
time.sleep(waitTime)
waitTime = waitTimeDefault # reset wait time back to default if it was changed
# Set day 2 to be used to see if the day has changed by comparing against day 1
day2 = dt.now().strftime("%d")
# If day has changed, open new data file, generate moisture and temperature plots, and reset arrays and day 1
if day1 != day2:
file.close()
dt_string = dt.now().strftime("D%dM%mY%YH%HM%MS%S")
file = open("/home/pi/CompostMonitoringSystem/CompostMonitoringData/" + dt_string + ".txt", "w")
fig, ax = plt.subplots()
ax.plot(timeS, temp1, label='temp 1')
ax.plot(timeS, temp2, label='temp 2')
ax.plot(timeS, temp3, label='temp 3')
ax.set_xlabel('time, s')
ax.set_ylabel('temp, deg F')
ax.set_title("Temperature vs. Time")
ax.legend()
plt.savefig('/home/pi/CompostMonitoringSystem/TemperaturePlots/' + dt_string + '.png', bbox_inches='tight')
fig, ax = plt.subplots()
ax.plot(timeS, moist1, label='moisture 1')
ax.plot(timeS, moist2, label='moisture 2')
ax.plot(timeS, moist3, label='moisture 3')
ax.set_xlabel('time, s')
ax.set_ylabel('moisture, ?')
ax.set_title("Moisture vs. Time")
ax.legend()
plt.savefig('/home/pi/CompostMonitoringSystem/MoisturePlots/' + dt_string + '.png', bbox_inches='tight')
temp1 = []
temp2 = []
temp3 = []
moist1 = []
moist2 = []
moist3 = []
timeS = []
day1 = dt.now().strftime("%d")
# reset threshold flags
for i in range(len(thresholdFlags)):
thresholdFlags[i] = 0
main()