From 0a8f8d3e1aad2b8252b24341a87cff65e055f0a4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 9 Feb 2022 23:36:39 -0500 Subject: [PATCH] Added some settings for cleaning dates. Added Testing feature which overrides notification schedule and sends notifcations every one minute. It also sends out the full feed/clean notifications. Set Timezone. Added notification logic. --- app.py | 75 +++++++++++++++++++++++++++++++------------- sendNotifications.py | 59 ++++++++++++++++++++++++++++++++++ templates/index.html | 11 +++++-- 3 files changed, 121 insertions(+), 24 deletions(-) create mode 100644 sendNotifications.py diff --git a/app.py b/app.py index 779262b..2209709 100644 --- a/app.py +++ b/app.py @@ -1,14 +1,18 @@ from flask import Flask, render_template, request, flash, redirect import datetime +import sendNotifications from sqlalchemy import create_engine, Column, Integer, String, Date from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from flask_apscheduler import APScheduler +# Set to True to simplify testing +TESTING = False + class Config: SCHEDULER_API_ENABLED = True - + SCHEDULER_TIMEZONE = 'US/Eastern' app = Flask(__name__) app.config['SECRET_KEY'] = 'fa6166b0218186fb852429060105aca18e0f979240be8ebf' @@ -16,7 +20,8 @@ app.config.from_object(Config()) scheduler = APScheduler() scheduler.init_app(app) - +# Needed below to access native APSchedule objects +sched = scheduler.scheduler Base = declarative_base() @@ -58,23 +63,46 @@ SettingsMetadata.__table__.create(bind=engine, checkfirst=True) Session = sessionmaker(bind=engine) -@scheduler.task('cron', id='send_notifications', minute='*') -def notifications(): +@scheduler.task('cron', id='send_notifications', hour='10') +def Checknotifications(): session = Session() - notifications = {'text': '', 'email': ''} - notifications['text'] = session.query(Settings).filter_by(settingType=1).first().settingValue - notifications['email'] = session.query(Settings).filter_by(settingType=2).first().settingValue + nextFeed = session.query(Dates).filter_by(dateTypeID=3).first().dateValue + nextClean = session.query(Dates).filter_by(dateTypeID=5).first().dateValue + clean = False + today = datetime.date.today() - if notifications['text']: - print('will send text') - if notifications['email']: - print('will send email') - print('checked') + if nextClean == today or TESTING is True: + clean = True + else: + clean = False + # Check if notififcations need to be sent out + if nextFeed == today or TESTING is True: + # Check what notifications should be sent out grab the grab relevant contact info and pass it to the appropriate + # notification method + notifications = {'text': session.query(Settings).filter_by(settingType=1).first().settingValue, + 'email': session.query(Settings).filter_by(settingType=2).first().settingValue} + if notifications['text']: + contact = session.query(Settings).filter_by(settingType=4).first().settingValue + sendNotifications.sendText(contact, clean) + if notifications['email']: + contact = session.query(Settings).filter_by(settingType=5).first().settingValue + sendNotifications.sendEmail(contact, clean) + print('sent any selected notifications') + # print(today) + # print(nextFeed) + else: + print('Not time to Send') + session.close() scheduler.start() +# If in testing mode reschedule the notification check to run every minute +if TESTING is True: + sched.reschedule_job('send_notifications', trigger='cron', minute='*') + print('Sending notifications every minute') + @app.route('/', methods=('GET', 'POST')) @app.route('/index.html', methods=('GET', 'POST')) @@ -87,23 +115,25 @@ def index(): return redirect('install.html') # Init the dates dict - dates = {'plant': '', 'last': '', 'next': '', 'freq': ''} - alerts = {'text': '', 'email': ''} - # alerts = {'text': False, 'email': True} - - # Get the feeding frequency and set it to an int - dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue) - + dates = {'plant': '', 'last': '', 'next': '', 'freq': '', 'lastClean': '', 'nextClean': '', 'cleanFreq': ''} alerts = {'text': False, 'email': False} + # Get the feeding frequency and cleaning frequency set them to ints + dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue) + dates['cleanFreq'] = int(session.query(Settings).filter_by(settingType=6).first().settingValue) + # If clicked the update button for dates, grab the new values and save them to the db. Then render the template if request.method == 'POST': dates['plant'] = request.form['plantDate'] dates['last'] = request.form['lastDate'] dates['next'] = datetime.datetime.strptime(dates['last'], '%Y-%m-%d') + datetime.timedelta(days=dates['freq']) + dates['lastClean'] = request.form['lastClean'] + dates['cleanFreq'] = datetime.datetime.strptime(dates['lastClean'], '%Y-%m-%d') + datetime.timedelta(days=dates['cleanFreq']) session.query(Dates).filter_by(dateTypeID=1).update({Dates.dateValue: dates['plant']}) session.query(Dates).filter_by(dateTypeID=2).update({Dates.dateValue: dates['last']}) session.query(Dates).filter_by(dateTypeID=3).update({Dates.dateValue: dates['next']}) + session.query(Dates).filter_by(dateTypeID=4).update({Dates.dateValue: dates['lastClean']}) + session.query(Dates).filter_by(dateTypeID=5).update({Dates.dateValue: dates['cleanFreq']}) # grab text message alert box. Set 'True' if checked or null if unchecked if request.form.get('AlertText'): @@ -115,7 +145,7 @@ def index(): alerts['email'] = 'True' else: alerts['email'] = None - + # Update the alert settings to the database session.query(Settings).filter_by(settingType=1).update({Settings.settingValue: alerts['text']}) session.query(Settings).filter_by(settingType=2).update({Settings.settingValue: alerts['email']}) @@ -127,6 +157,8 @@ def index(): dates['plant'] = session.query(Dates).filter_by(dateTypeID=1).first().dateValue dates['last'] = session.query(Dates).filter_by(dateTypeID=2).first().dateValue dates['next'] = session.query(Dates).filter_by(dateTypeID=3).first().dateValue + dates['lastClean'] = session.query(Dates).filter_by(dateTypeID=4).first().dateValue + dates['nextClean'] = session.query(Dates).filter_by(dateTypeID=5).first().dateValue alerts['text'] = session.query(Settings).filter_by(settingType=1).first().settingValue alerts['email'] = session.query(Settings).filter_by(settingType=2).first().settingValue @@ -172,7 +204,7 @@ def install(): session.add(Settings(settingType=3, settingValue='14')) session.add(Settings(settingType=4, settingValue=None)) session.add(Settings(settingType=5, settingValue=None)) - + session.add(Settings(settingType=6, settingValue='28')) # Populate SettingsMetadata session.add(SettingsMetadata(settingTypeID=1, settingTypeName='Text')) @@ -180,6 +212,7 @@ def install(): session.add(SettingsMetadata(settingTypeID=3, settingTypeName='Feeding Frequency')) session.add(SettingsMetadata(settingTypeID=4, settingTypeName='Alert Phone Number')) session.add(SettingsMetadata(settingTypeID=5, settingTypeName='Alert Email')) + session.add(SettingsMetadata(settingTypeID=6, settingTypeName='Cleaning Frequency')) session.commit() diff --git a/sendNotifications.py b/sendNotifications.py new file mode 100644 index 0000000..cfc119f --- /dev/null +++ b/sendNotifications.py @@ -0,0 +1,59 @@ +from twilio.rest import Client +from smtplib import SMTP +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +from email.mime.base import MIMEBase + +# Twilio Account Setup +account_sid = 'AC051785f6dd5a93184641d01103eb8cd4' +auth_token = 'd40c831e56785afaa9294fd3c5a88e6e' +client = Client(account_sid, auth_token) + +# Email Account Setup +smtp_server = 'in-v3.mailjet.com' +smtp_port = 587 + + +def sendText(contact, clean): + + if clean is True: + cleanMsg = 'Feed the Hydroponics. It also needs to be cleaned today' + else: + cleanMsg = 'Feed the Hydroponics.' + + message = client.messages.create( + messaging_service_sid='MG864145600a43493122488250262ccbc9', + body=cleanMsg, + to=contact + ) + return + + +def sendEmail(contact, clean): + + from_addr = 'Hydro@dandembinski.com' + + smtp = SMTP() + smtp.connect(smtp_server, smtp_port) + smtp.login('bef546c3019739fff8a2dbbfc26ec74a', 'dbe2b63a3f1fa5e4f00217c2784a8055') + + if clean is True: + cleanMsg = 'Feed the Hydroponics. It also needs to be cleaned today' + else: + cleanMsg = 'Feed the Hydroponics.' + + bodyHTML = MIMEText(cleanMsg, "html") + + msg = MIMEMultipart() + msg['Subject'] = 'Feed Hydroponics' + msg['To'] = contact + msg['From'] = from_addr + + msg.add_header('Content-Type', 'text/html') + msg.attach(bodyHTML) + + try: + smtp.send_message(msg) + except Exception as e: + print(e) + return diff --git a/templates/index.html b/templates/index.html index 8e83e92..7209dda 100644 --- a/templates/index.html +++ b/templates/index.html @@ -2,18 +2,23 @@ {% block content %}

Information

+

Feeding Information



- - + + Next Feed Date: {{ plant.next }}
Feed Frequency: {{ plant.freq }} days +

Cleaning Information

+ +
-
+ Next Clean Date: {{ plant.nextClean }}

Alerts