Archived
1
0

Compare commits

...

14 Commits

Author SHA1 Message Date
Shaun Setlock
b1782a703c Consolidating requirements. 2025-04-26 22:10:26 -04:00
Shaun Setlock
befdbb89fb Relocating requirements.txt to project root. 2025-04-26 22:07:12 -04:00
Shaun Setlock
b12e78d6e6 Relocating requirements.txt to project root. 2025-04-26 22:06:51 -04:00
Shaun Setlock
7bbdbc8998 Working automatic mode.No DB stuff yet. 2021-11-12 15:23:57 -05:00
Shaun Setlock
dbbf6f7b42 Pushing some work on automatic mode. 2021-11-12 13:55:45 -05:00
Shaun Setlock
9275f3a5a3 Starting to work on functional description. 2021-11-06 21:10:28 -04:00
Shaun Setlock
065413bcd0 Wrote working manual mode script. 2021-11-06 19:06:43 -04:00
Shaun Setlock
4970653c0c Merge branch 'master' of ssh://gitea.setlock.xyz:2222/shaun/garden 2021-11-06 16:59:29 -04:00
Shaun Setlock
5619ac4e17 Updating sample scripts to use final pin assignments. 2021-11-06 16:54:38 -04:00
Shaun Setlock
07083c6e71 Some working db writer code. 2021-10-23 07:47:59 -04:00
Shaun Setlock
974a914282 Starting code for writing to Postgres db. 2021-10-22 21:14:45 -04:00
Shaun Setlock
0a0a94ba51 Minor changes to variable naming in pb.py 2021-10-18 20:22:07 -04:00
Shaun Setlock
ab811ae31b Fixing date in DHT22 print formatting. 2021-10-18 15:53:27 -04:00
Shaun Setlock
0f142124a8 Adding relay output test program. 2021-10-17 20:55:25 -04:00
15 changed files with 1013 additions and 983 deletions

2
.gitignore vendored
View File

@@ -138,3 +138,5 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
# Secrets
.creds*

View File

@@ -1,3 +1,14 @@
# garden # garden
Python project for building an indoor garden with the Setlock ladies. Python project for building an indoor garden with the Setlock ladies.
## BCM Pin Assignments
| BCM Number | Device | Function |
|------------|--------|----------|
| 4 | Green Pushbutton | Sequence Start |
| 27 | Yellow Pushbutton | Lamp |
| 13 | Blue Pushbutton | Water Pump |
| 26 | Relay 1 | N.O. Pump |
| 20 | Relay 2 | *Unassigned* |
| 21 | Relay 3 | N.O. Lamp |

33
automatic/input.py Normal file
View File

@@ -0,0 +1,33 @@
#! env/bin/python3
import RPi.GPIO as GPIO
import time
from datetime import datetime
def get_pin_input():
# Pin Assignments
PB1_BCM = 4 # Green
PB2_BCM = 27 # Yellow
PB3_BCM = 13 # Blue
RELAY1_PIN = 26 # Water Pump
RELAY2_PIN = 20 # Unassigned
RELAY3_PIN = 21 # Lamp
# Get current time.
now = datetime.now()
hour = now.hour
minute = now.minute
# Define alias variables for input devices.
inputs = {
'green_button' : GPIO.input(PB1_BCM),
'yellow_button' : GPIO.input(PB2_BCM),
'blue_button' : GPIO.input(PB3_BCM),
'pump' : GPIO.input(RELAY1_PIN),
'lamp' : GPIO.input(RELAY3_PIN),
'hour' : hour,
'minute' : minute,
}
return inputs

20
automatic/output.py Normal file
View File

@@ -0,0 +1,20 @@
#! env/bin/python3
import RPi.GPIO as GPIO
import time
from datetime import datetime
def write_pin_output(outputs):
# Setup for Hardware
RELAY1_PIN = 26 # Water Pump
RELAY2_PIN = 20 # Unassigned
RELAY3_PIN = 21 # Lamp
# Write outputs.
if outputs['detect']:
time.sleep(1.0)
GPIO.output(RELAY1_PIN, outputs['pump'])
GPIO.output(RELAY2_PIN, False)
GPIO.output(RELAY3_PIN, outputs['lamp'])

69
automatic/routine.py Normal file
View File

@@ -0,0 +1,69 @@
#! env/bin/python3
import RPi.GPIO as GPIO
import time
from input import get_pin_input
from state_trans import check_state
from output import write_pin_output
if __name__ == "__main__":
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Pin Assignments
PB1_BCM = 4 # Green
PB2_BCM = 27 # Yellow
PB3_BCM = 13 # Blue
RELAY1_PIN = 26 # Water Pump
RELAY2_PIN = 20 # Unassigned
RELAY3_PIN = 21 # Lamp
# Setup the Inputs to use the internal pull-down.
GPIO.setup(PB1_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(PB2_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(PB3_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Setup the Outputs.
GPIO.setup(RELAY1_PIN, GPIO.OUT)
GPIO.setup(RELAY2_PIN, GPIO.OUT)
GPIO.setup(RELAY3_PIN, GPIO.OUT)
try:
auto_mode = False
while True:
# Detect user input.
inputs = get_pin_input()
# Activate auto mode if the Green PB is pressed.
if auto_mode or inputs['green_button'] == True:
inputs['mode'] = "AUTO"
auto_mode = True
# Activate manual mode if the Yellow or Blue PB's are pressed.
if not auto_mode or inputs['yellow_button'] == True or inputs['blue_button'] == True:
inputs['mode'] = "MANUAL"
auto_mode = False
# Make any transitions based on mode and inputs.
outputs = check_state(inputs)
# Write the outputs which correspond to the desired state.
write_pin_output(outputs)
# Avoid maxxing out a single thread.
time.sleep(0.1)
# Cleanup on Exit.
finally:
GPIO.output(RELAY1_PIN, False)
GPIO.output(RELAY2_PIN, False)
GPIO.output(RELAY3_PIN, False)
GPIO.cleanup()

68
automatic/state_trans.py Normal file
View File

@@ -0,0 +1,68 @@
#! env/bin/python3
import RPi.GPIO as GPIO
import time
from datetime import datetime
def check_state(inputs):
# Define alias variables for input devices.
green_button = inputs['green_button']
yellow_button = inputs['yellow_button']
blue_button = inputs['blue_button']
# Define state variables for each of the output devices.
pump_state = inputs['pump']
lamp_state = inputs['lamp']
# Get mode and schedule information.
mode = inputs['mode']
hour = inputs['hour']
minute = inputs['minute']
# Determine state.
# Assume no change in state.
pump_out = pump_state
lamp_out = lamp_state
# Automatic mode.
if mode == "AUTO":
detect = False
if 6 < hour < 22:
lamp_out = True
pump_out = True
else:
lamp_out = False
pump_out = False
# Manual mode.
if mode == "MANUAL":
detect = False
# Pump Flip-Flop
if not detect and blue_button and pump_state:
pump_out = False
detect = True
if not detect and blue_button and not pump_state:
pump_out = True
detect = True
# Lamp Flip-Flop
if not detect and yellow_button and lamp_state:
lamp_out = False
detect = True
if not detect and yellow_button and not lamp_state:
lamp_out = True
detect = True
# Define alias variables for input devices.
outputs = {
'detect' : detect,
'pump' : pump_out,
'lamp' : lamp_out,
}
return outputs

73
db_tools/db_writer.py Normal file
View File

@@ -0,0 +1,73 @@
#! env/bin/python3
# import the psycopg2 database adapter for PostgreSQL
import psycopg2
from psycopg2.extras import Json
import json
import sys
def connect_db(db: str,host: str,user: str,passwd: str):
try:
# declare a new PostgreSQL connection object
conn = psycopg2.connect(
dbname = db,
user = user,
host = host,
password = passwd,
# attempt to connect for 3 seconds then raise exception
connect_timeout = 3
)
except (Exception, psycopg2.Error) as err:
#print ("\npsycopg2 connect error:", err)
conn = None
return conn
def get_db_creds(file: str):
with open(file) as cred_file:
creds = json.load(cred_file)
return creds
def insert_data(conn, data):
# insert a new vendor into the vendors table
sql = """
INSERT INTO
air(datetime, temperature, humidity)
VALUES
(%s, %s, %s)
"""
try:
# open cursor on our db connection
cur = conn.cursor()
# execute the INSERT statement
data = (data["datetime"], data["temperature"], data["humidity"])
cur.execute(sql,data)
# commit the changes to the database
conn.commit()
# close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
if __name__ == "__main__":
data = {
"datetime": "2021-10-23 01:58:08.205911",
"temperature": "73.4",
"humidity": "49.2"
}
creds = get_db_creds("./.creds.json")
conn = connect_db(creds["db"], creds["host"], creds["user"], creds["passwd"])
insert_data(conn, data)

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ if __name__ == "__main__":
# Setup for Hardware # Setup for Hardware
DHT22_PIN = 4 DHT22_PIN = 4
dht_device = adafruit_dht.DHT22(4) dht_device = adafruit_dht.DHT22(4)
file = '/home/pi/code/dht22/log.csv' file = '/home/pi/code/garden/dht22/log.csv'
with open(file,'a') as f: with open(file,'a') as f:
@@ -29,10 +29,10 @@ if __name__ == "__main__":
data = get_sensor_data(dht22=dht_device) data = get_sensor_data(dht22=dht_device)
if data: if data:
temperature, humidity = get_sensor_data(dht22=dht_device) temperature, humidity = get_sensor_data(dht22=dht_device)
current_time = datetime.now().strftime("%H:%M:%S") current_time = datetime.now().strftime("%D %H:%M:%S")
print(f'{humidity:.2f}% {temperature:.2f}degF') print(f'{humidity:.2f}% {temperature:.2f}degF')
f.write(f'{current_time},{humidity:.2f},{temperature:.2f}\n') f.write(f'{current_time},{humidity:.2f},{temperature:.2f}\n')
time.sleep(60) time.sleep(14.9)
else: else:
time.sleep(0.1) time.sleep(0.1)

28
functional_decription.md Normal file
View File

@@ -0,0 +1,28 @@
# Functional Description - Garden Logic
### Table of Contents
1. Routines
1. Scan Inputs
2. Collect Program State
3. Manipulate Program State
4. Write Outputs
5. Log to Database
2. References
## Routines
### Scan Inputs
`./input/inputs.py`
### Collect Program State
`./states/state.py`
### Manipulate Program State
`./states/state.py`
### Write Outputs
`./output/outputs.py`
### Log to Database
`./logging/db.py`

77
manual/manual.py Normal file
View File

@@ -0,0 +1,77 @@
#! env/bin/python3
import RPi.GPIO as GPIO
import time
if __name__ == "__main__":
# Setup for Hardware
PB1_BCM = 4 # Green
PB2_BCM = 27 # Yellow
PB3_BCM = 13 # Blue
RELAY1_PIN = 26 # Water Pump
RELAY2_PIN = 20 # Unassigned
RELAY3_PIN = 21 # Lamp
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Setup the Inputs to use the internal pull-down.
GPIO.setup(PB1_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(PB2_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(PB3_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Setup the outputs to be initialized as OFF.
GPIO.setup(RELAY1_PIN, GPIO.OUT)
GPIO.output(RELAY1_PIN, False)
GPIO.setup(RELAY2_PIN, GPIO.OUT)
GPIO.output(RELAY2_PIN, False)
GPIO.setup(RELAY3_PIN, GPIO.OUT)
GPIO.output(RELAY3_PIN, False)
# Define alias variables for input devices.
green_button = False
yellow_button = False
blue_button = False
# Define state variables for each of the output devices.
pump_state = False
lamp_state = False
# Begin detected presses.
try:
while True:
# Detect inputs.
detect = False
green_button = GPIO.input(PB1_BCM)
yellow_button = GPIO.input(PB2_BCM)
blue_button = GPIO.input(PB3_BCM)
# Determine state.
if not detect and blue_button and pump_state:
pump_state = False
detect = True
if not detect and blue_button and not pump_state:
pump_state = True
detect = True
# Lamp
if not detect and yellow_button and lamp_state:
lamp_state = False
detect = True
if not detect and yellow_button and not lamp_state:
lamp_state = True
detect = True
# Write outputs.
if detect:
time.sleep(1.0)
GPIO.output(RELAY1_PIN, pump_state)
GPIO.output(RELAY3_PIN, lamp_state)
# Avoid running a single thread maxxed out.
time.sleep(0.1)
finally:
GPIO.cleanup()

View File

@@ -6,21 +6,34 @@ import time
if __name__ == "__main__": if __name__ == "__main__":
# Setup for Hardware # Setup for Hardware
PB_PIN = 22 PB1_BCM = 4 # Green
PB2_BCM = 27 # Yellow
PB3_BCM = 13 # Blue
GPIO.setmode(GPIO.BCM) GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False) GPIO.setwarnings(False)
# Use the internal pull-down. # Use the internal pull-down.
GPIO.setup(PB_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.setup(PB1_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(PB2_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(PB3_BCM, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# Begin detected presses. # Begin detected presses.
i = 0 i = 0
try: try:
while True: while True:
if not GPIO.input(PB_PIN): # Green
if GPIO.input(PB1_BCM):
i += 1 i += 1
print(f"Hi Gabby! Did you push the button? i = {i}") print(f"Hi Gabby! Did you push the GREEN button? i = {i}")
# Yellow
if GPIO.input(PB2_BCM):
i += 1
print(f"Hi Gabby! Did you push the YELLOW button? i = {i}")
# Blue
if GPIO.input(PB3_BCM):
i += 1
print(f"Hi Gabby! Did you push the BLUE button? i = {i}")
time.sleep(0.1) time.sleep(0.1)
finally: finally:

37
relay/relay.py Normal file
View File

@@ -0,0 +1,37 @@
#! env/bin/python3
import RPi.GPIO as GPIO
import time
if __name__ == "__main__":
# Setup for Hardware
RELAY1_PIN = 26
RELAY2_PIN = 20
RELAY3_PIN = 21
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# Setup the output pin; initialize OFF.
GPIO.setup(RELAY1_PIN, GPIO.OUT)
GPIO.output(RELAY1_PIN, False)
GPIO.setup(RELAY2_PIN, GPIO.OUT)
GPIO.output(RELAY2_PIN, False)
GPIO.setup(RELAY3_PIN, GPIO.OUT)
GPIO.output(RELAY3_PIN, False)
# Short toggle.
i = 0
try:
time.sleep(10.0)
GPIO.output(RELAY1_PIN, True)
GPIO.output(RELAY3_PIN, True)
time.sleep(60.0)
GPIO.output(RELAY1_PIN, False)
GPIO.output(RELAY3_PIN, False)
time.sleep(1.0)
finally:
GPIO.cleanup()

13
relay/requirements.txt Normal file
View File

@@ -0,0 +1,13 @@
black==21.9b0
click==8.0.3
importlib-metadata==4.8.1
mypy-extensions==0.4.3
pathspec==0.9.0
pkg-resources==0.0.0
platformdirs==2.4.0
regex==2021.10.8
RPi.GPIO==0.7.0
tomli==1.2.1
typed-ast==1.4.3
typing-extensions==3.10.0.2
zipp==3.6.0

13
requirements.txt Normal file
View File

@@ -0,0 +1,13 @@
black==21.9b0
click==8.0.3
importlib-metadata==4.8.1
mypy-extensions==0.4.3
pathspec==0.9.0
pkg-resources==0.0.0
platformdirs==2.4.0
regex==2021.10.8
RPi.GPIO==0.7.0
tomli==1.2.1
typed-ast==1.4.3
typing-extensions==3.10.0.2
zipp==3.6.0