-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbarnhardware.py
More file actions
249 lines (238 loc) · 7.91 KB
/
barnhardware.py
File metadata and controls
249 lines (238 loc) · 7.91 KB
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
# Barn Automation Hardware Interface
import time
import sys
import glob
import socket
try:
from pijuice import PiJuice # Import pijuice module
from RPLCD import CharLCD # Import Raspberry Pi LCD Controller
import RPi.GPIO as GPIO # Import GPIO Controller
GPIO.setwarnings(False) # Disable GPIO Warnings
pijuice = PiJuice(1, 0x14) # Instantiate PiJuice interface object
except:
print("Failed to import. Testing on Windows? Try on RPi!")
time.sleep(5)
sys.exit()
# Define Shared (Global) Variable
lcdmsg1 = ''
lcdmsg2 = ''
# Define LCD Shape
col = 24
row = 2
# Define LCD Pins
rs = 21
en = 23
d4 = 29
d5 = 35
d6 = 31
d7 = 33
# Define Relay Control GPIO Pins
RLY1 = 37
RLY2 = 38
RLY3 = 40
# Define Add'l GPIO Pins
gLED = 16
rLED = 19
gBTN = 13
rBTN = 11
phto = 12
# Define Add'l Parameters
start_time = 0.01
# Define Temperature Probe Parameters
try:
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
except:
device_file = ''
# Define Functions Required to Read Ambient Temperature
def read_temp_raw():
if device_file == '':
raise ValueError("No Available DS18B20 Sensor.")
with open(device_file, 'r') as f:
lines = f.readlines()
return lines
def read_temp(scale='f'):
# Wrap Temperature Reading in try/except
try:
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
if scale.upper() == 'F':
return( temp_f )
elif scale.upper() == 'C':
return( temp_c )
else:
return
except:
if scale.upper() == 'F':
return( 0 ) # default to 0-degrees-F
elif scale.upper() == 'C':
return( -20 ) # default to -20-degrees-C
else:
return
# Define Hardware Control Class
class BarnHardware:
def __init__(self):
# Initialize LCD Display
self.lcd = CharLCD(numbering_mode=GPIO.BOARD, cols=col, rows=row,
pin_rs=rs, pin_e=en, pins_data=[d4,d5,d6,d7])
time.sleep(start_time)
self.lcd = CharLCD(numbering_mode=GPIO.BOARD, cols=col, rows=row,
pin_rs=rs, pin_e=en, pins_data=[d4,d5,d6,d7])
# Initialize Button and LED GPIO Pins
GPIO.setup(gLED, GPIO.OUT, initial=0)
GPIO.setup(rLED, GPIO.OUT, initial=0)
GPIO.setup(RLY1, GPIO.OUT, initial=0)
GPIO.setup(RLY2, GPIO.OUT, initial=0)
GPIO.setup(RLY3, GPIO.OUT, initial=0)
GPIO.setup(phto, GPIO.IN)
GPIO.setup(gBTN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(rBTN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Define Get Functions
def get_btn(self):
grn = GPIO.input(gBTN) == GPIO.HIGH
red = GPIO.input(rBTN) == GPIO.HIGH
return(grn,red)
def get_photo(self):
light = GPIO.input(phto) == GPIO.HIGH
return(light)
def get_lcd(self):
global lcdmsg1, lcdmsg2
return(lcdmsg1.replace('\0',' '),lcdmsg2.replace('\0',' '))
def get_led(self):
L1 = GPIO.input(gLED) == GPIO.HIGH
L2 = GPIO.input(rLED) == GPIO.HIGH
return(L1,L2)
def get_rly(self):
r1 = GPIO.input(RLY1) == GPIO.HIGH
r2 = GPIO.input(RLY2) == GPIO.HIGH
r3 = GPIO.input(RLY3) == GPIO.HIGH
return(r1,r2,r3)
def get_bat_sta(self):
# Collect data structure and extract error
sta = pijuice.status.GetStatus()['data']
err = not( sta['error'] == 'NO_ERROR' )
return(err)
def get_bat_chg(self):
chg = pijuice.status.GetChargeLevel()['data']
return(chg) # percent charged
def get_pwr_src(self):
src = pijuice.status.GetStatus()['data']['powerInput']
active = (src == 'PRESENT')
return(active,src)
def get_voltage(self):
v = pijuice.status.GetBatteryVoltage()['data']
return(float(v)*0.001)
def get_current(self):
i = pijuice.status.GetBatteryCurrent()['data']
return(float(i))
def get_vbus_5v(self):
v = pijuice.status.GetIoVoltage()['data']
return(float(v)*0.001)
def get_ibus_5v(self):
i = pijuice.status.GetIoCurrent()['data']
return(float(i))
def get_bat_led(self,LED=None):
if LED==None:
return(pijuice.status.GetLedState('D1')['data'],
pijuice.status.GetLedState('D2')['data'])
if isinstance(LED, int): # Condition Input
LED = {1:'D1', 2:'D2'}[LED]
return(pijuice.status.GetLedState(LED)['data'])
def get_temp(self,scale='f',fmt=None):
# Mask Temperature Function for Ease
temp = read_temp(scale=scale)
if isinstance(fmt,str):
temp = fmt.format(temp)
return(temp)
def get_ip_adr(self):
ip_address = ''
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8",80))
ip_address = s.getsockname()[0]
s.close()
return(ip_address)
# Define Callback Specifiers
def set_grn_callback(self,func,opt=GPIO.RISING):
GPIO.add_event_detect(gBTN,opt,callback=func,bouncetime=100)
def set_red_callback(self,func,opt=GPIO.RISING):
GPIO.add_event_detect(rBTN,opt,callback=func,bouncetime=100)
# Define Set Functions for LED's and LCD
def set_led(self,grn=False,red=False):
# Set LEDs
GPIO.output(gLED,grn)
GPIO.output(rLED,red)
def set_bat_led(self,LED,r,g,b):
if isinstance(LED, int): # Condition Input
LED = {1:'D1', 2:'D2', 3:'D3'}[LED]
pijuice.status.SetLedState(LED, [r,g,b])
def set_rly(self,rly,status):
# Define LUT
rly = [RLY1,RLY2,RLY3][rly]
# Set Relays
GPIO.output(rly,status)
def set_lcd(self,LINE1='',LINE2=''):
global lcdmsg1, lcdmsg2
NL = 16*' ' # 16 Spaces
L2MX = 8
# Condition and Test Inputs
LINE1 = str(LINE1)
LINE2 = str(LINE2)
if len(LINE1) > col:
print("WARNING: Line 1 is longer than "+str(col)+" characters.")
if len(LINE2) > L2MX:
print("WARNING: Line 2 is longer than "+str(L2MX)+" characters.")
# Manage LCD Strings
lcdmsg1 = '\r'+LINE1[:col].replace(' ','\0')
lcdmsg2 = NL+LINE2[:L2MX].replace(' ','\0')
# Update LCD
if __name__ == '__main__':
print("testing...",len(lcdmsg1),len(lcdmsg2))
# Clear LCD
self.lcd.clear()
# Write Message
self.lcd.write_string(lcdmsg2)
self.lcd.write_string(lcdmsg1)
# Define Test Method
if __name__ == '__main__':
try:
print("Testing Script Operation...")
print("Temperature:",read_temp(),"°F")
hdw = BarnHardware()
hdw.set_lcd("Outside Temperature:",str(round(read_temp(),2))+"'F")
ctr = 0
while(True):
time.sleep(1)
hdw.set_lcd("Outside Temperature:",str(round(read_temp(),2))+"'F")
g,r = hdw.get_btn()
hdw.set_led(g,r)
print("Light:",hdw.get_photo(),"\tBat:",hdw.get_bat_chg(),"%")
if ctr == 0:
hdw.set_rly(0,False)
hdw.set_rly(1,False)
hdw.set_rly(2,False)
ctr += 1
elif ctr == 1:
hdw.set_rly(0,True)
ctr += 1
elif ctr == 2:
hdw.set_rly(1,True)
ctr += 1
elif ctr == 3:
hdw.set_rly(2,True)
ctr += 1
else:
ctr = 0
finally:
hdw.set_lcd('','')
hdw.set_rly(False,False,False)
time.sleep(0.5)
GPIO.cleanup()
# END