/
pi.py
239 lines (189 loc) · 6.87 KB
/
pi.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
import time
import threading
import sys
import RPi.GPIO as gpio
import paho.mqtt.client as mqtt
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email import encoders
import picamera
import os
import datetime
############### Settings ##################
client = mqtt.Client("EDEN_PI", clean_session=False)
client.username_pw_set("Cloud instance name", "Password")
#weather = Weather(unit=Unit.CELSIUS)
#location = weather.lookup_by_location('Toronto')
#condition = location.condition
#temperature = condition.temp
subTopic = "GPIO/instructions"
pubTopic = "GPIO/Data"
path = "/home/pi/Desktop/" #path of image file
email = "User email"
pump = 18
trig = 20
echo = 21
moist = 12
flag = True
############### Settings ##################
#Setup ports with output direction
def gpioSetup():
gpio.setwarnings(False)
gpio.setmode(gpio.BCM)
#Pump power
gpio.setup(pump, gpio.OUT,initial=0)
#Ultrasonic sensor
gpio.setup(trig, gpio.OUT, initial=0)
gpio.setup(echo, gpio.IN)
#Humidity sensor
gpio.setup(moist, gpio.IN)
def takePicture():
global path
camera = picamera.PiCamera()
camera.capture(path+"plants.jpg")
camera.close()
#end def
def sendPicture():
global path
server = smtplib.SMTP_SSL('smtp.gmail.com',465)
#eden garden gmail
me = ""
#and password
password = ""
server.login(me,password)
image = MIMEImage(open(path+"plants.jpg",'rb').read(),name="plants.jpg")
msg = MIMEMultipart()
msg['Subject'] = "Picture of your plants"
msg['From'] = me
msg['To'] = email
msg.attach(image)
server.sendmail(me,msg['To'],msg.as_string())
server.quit()
os.remove(path+"plants.jpg")
#Funcion to calculate water level
def water():
global flag
try:
while True:
gpio.output(trig,False)
time.sleep(1)
gpio.output(trig,True)
time.sleep(0.00001)
gpio.output(trig,False)
while gpio.input(echo) == 0:
pulse_start = time.time()
while gpio.input(echo) == 1:
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start
distance = pulse_duration * 17150
distance = round(distance,2)
#find percentage remaining based pulse duration and container size
percentage = int(((distance - 4.5)*100)/9.8)
#Check for oddities and only publish the ones that are less than 100%
if percentage < 130:
if percentage <=0:
percentage = 0
elif percentage >=100:
percentage = 100
client.publish(pubTopic,payload="wl"+str(100-percentage),qos=0)
#Check last watering status everyday at 10am
if datetime.datetime.now().hour == 10:
notify(flag)
flag = False
except Exception:
print(str(Exception))
#If date delt is 3 or more then send ser notification
def notify(flag):
global email
if flag:
#Open log file
file = open('log.txt','r')
month= file.readline()
day = file.readline()
#Calculate delta
last = datetime.datetime(2019,int(month),int(day))
date = datetime.datetime.today()
substract = date - last
#Email
if int(substract.days) >= 3:
msg = MIMEMultipart()
msg["From"] = me
msg["To"] = email
msg["Subject"] = "Eden System Notification"
msg.attach(MIMEText("Your plants have not been watered in more than three days!",'plain'))
server = smtplib.SMTPserver = smtplib.SMTP_SSL('smtp.gmail.com',465)
server.login(me,"tpj_655_eden")
server.sendmail(me,msg['To'],msg.as_string())
server.quit()
print("notified")
file.close()
#Pump activation
def activate():
#log the date it was activated
file = open('demo.txt','w')
file.write(str(datetime.datetime.today().month)+"\n")
file.write(str(datetime.datetime.today().day))
file.close()
#Create pwm object
pwmPump = gpio.PWM(pump,1000)
DC = 0
pwmPump.start(DC)
#Increment solowly the dty cycle when started
while DC <= 99:
DC += 33
pwmPump.ChangeDutyCycle(DC)
time.sleep(1)
time.sleep(3)
pwmPump.stop()
gpio.output(pump,0)
#Publish output from humidity sensor
def humidity(moist):
time.sleep(0.1)
if gpio.input(moist):
client.publish(pubTopic, payload="m1", qos=0)
#Dry
print("dry")
else:
client.publish(pubTopic, payload="m0", qos=0)
#wet
print("wet")
# The callback for when the client connects
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe(subTopic)
# Checks message from published topic to instruct GPIOs
def on_message(client, userdata, msg):
global email
message = msg.payload.decode(encoding='UTF-8')
if message == "sync":
#Run sync function
print("Syncing Data!")
elif "pic" in message:
#Run camera function
takePicture()
sendPicture()
print("Picture taken and sent to ", email)
elif "pump" in message or "on" in message:
print("Watering system is on!")
activate()
elif "@" in message:
email = message
print("Email changed to "+email)
else:
print("Unknown message!")
#Connection events
client.on_connect = on_connect
client.on_message = on_message
client.connect("m15.cloudmqtt.com", 13159, 60)
#Enable GPIO configuration
gpioSetup()
state = bin(gpio.input(moist))
gpio.add_event_detect(moist, gpio.BOTH, bouncetime=300)
gpio.add_event_callback(moist,humidity)
thread = threading.Thread(target=water)
thread.daemon = True
thread.start()
# Infinite loop to keep program running until it is closed
client.loop_forever()