made concurrent PIRgate class

This commit is contained in:
Brennen Raimer
2019-01-18 16:29:23 -05:00
parent 699b700705
commit ef828a27f4

View File

@@ -7,49 +7,83 @@ import MySQLdb
from time import sleep from time import sleep
from datetime import datetime from datetime import datetime
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
from getpass import getpass
from multiprocessing import Queue
from concurrent.futures import ProcessPoolExecutor, CancelledError, wait
class PIRgate:
def __init__(self, hostname, username, password, database):
# Set RPi GPIO Mode # Set RPi GPIO Mode
GPIO.setmode(GPIO.BCM) GPIO.setmode(GPIO.BCM)
# Setup GPIO in and out pins # Setup GPIO in and out pins
PIR_PIN = 7 self.PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN) GPIO.setup(self.PIR_PIN, GPIO.IN)
# End GPIO setup # End GPIO setup
self.counts=Queue()
self._pool=ProcessPoolExecutor()
count = 0 def start(self):
try: try:
while True: self.event_listener = self._pool.submit(self.listen_for_events)
curr_date = datetime.now() self.db_writer = self._pool.submit(self.write_to_db, hostname, username, password, database)
if GPIO.input(PIR_PIN):
count += 1
# Open database connection
db = MySQLdb.connect("HOSTNAME","USERNAME","PASSWORD","DATABASE")
# prepare a cursor object using cursor() method
cursor = db.cursor()
if (curr_date.minute % 10 == 0) and (curr_date.second == 0):
try:
# Execute the SQL command
cursor.execute("INSERT INTO PIRSTATS (datetime, gatecount) VALUES ('%s', '%d')" % (curr_date.isoformat(' '), count))
# Commit your changes in the database
db.commit()
count = 0 #reset count for next 10-minute interval
except:
# Rollback in case there is any error
db.rollback()
# Disconnect from database server
db.close()
sleep(1)
except KeyboardInterrupt: except KeyboardInterrupt:
print("\nCtrl-C pressed cleaning up GPIO") print("\nCtrl-C pressed cleaning up GPIO")
self.event_listener.cancel()
self.db_writer.cancel()
GPIO.cleanup() GPIO.cleanup()
sys.exit(0) finally:
wait([self.event_listener,self.db_writer])
GPIO.cleanup()
def listen_for_events(self):
count = 0
while True:
try:
if GPIO.input(self.PIR_PIN):
count += 1
curr_date = datetime.now()
if (curr_date.minute % 10 == 0) and (curr_date.second == 0):
self.counts.put_nowait((curr_date,count))
count = 0
except (KeyboardInterrupt,CancelledError):
break
def write_to_db(self, hostname, username, password, database):
while True:
try:
time, count = self.counts.get()
with MySQLdb.connect(hostname,username,password,database) as db:
try:
db.cursor().execute("INSERT INTO PIRSTATS (datetime, gatecount) VALUES ('%s', '%d')" % (time.isoformat(' '), count))
except (KeyboardInterrupt,CancelledError):
db.rollback()
break
except:
db.rollback()
self.counts.put(time,count) #put the data back in queue to try writing it again
else:
db.commit()
finally:
db.close()
except (KeyboardInterrupt,CancelledError):
break
if __name__ == "__main__":
while True:
try:
hostname = input("DB Hostname: ")
database = input("Database: ")
username = input("Username: ")
password = getpass()
#just check the credentials by connecting to the db and closing
MySQLdb.connect(hostname, username, password, database).close()
except KeyboardInterrupt:
sys.exit(1)
except:
print("\nProblem connecting to the database. Check your credentials and try again \n")
continue
else:
break
PIRgate(hostname, username, password, database).start()