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.

This commit is contained in:
dan
2022-02-09 23:36:39 -05:00
parent 145b5ed21f
commit 0a8f8d3e1a
3 changed files with 121 additions and 24 deletions

75
app.py
View File

@@ -1,14 +1,18 @@
from flask import Flask, render_template, request, flash, redirect from flask import Flask, render_template, request, flash, redirect
import datetime import datetime
import sendNotifications
from sqlalchemy import create_engine, Column, Integer, String, Date from sqlalchemy import create_engine, Column, Integer, String, Date
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from flask_apscheduler import APScheduler from flask_apscheduler import APScheduler
# Set to True to simplify testing
TESTING = False
class Config: class Config:
SCHEDULER_API_ENABLED = True SCHEDULER_API_ENABLED = True
SCHEDULER_TIMEZONE = 'US/Eastern'
app = Flask(__name__) app = Flask(__name__)
app.config['SECRET_KEY'] = 'fa6166b0218186fb852429060105aca18e0f979240be8ebf' app.config['SECRET_KEY'] = 'fa6166b0218186fb852429060105aca18e0f979240be8ebf'
@@ -16,7 +20,8 @@ app.config.from_object(Config())
scheduler = APScheduler() scheduler = APScheduler()
scheduler.init_app(app) scheduler.init_app(app)
# Needed below to access native APSchedule objects
sched = scheduler.scheduler
Base = declarative_base() Base = declarative_base()
@@ -58,23 +63,46 @@ SettingsMetadata.__table__.create(bind=engine, checkfirst=True)
Session = sessionmaker(bind=engine) Session = sessionmaker(bind=engine)
@scheduler.task('cron', id='send_notifications', minute='*') @scheduler.task('cron', id='send_notifications', hour='10')
def notifications(): def Checknotifications():
session = Session() session = Session()
notifications = {'text': '', 'email': ''} nextFeed = session.query(Dates).filter_by(dateTypeID=3).first().dateValue
notifications['text'] = session.query(Settings).filter_by(settingType=1).first().settingValue nextClean = session.query(Dates).filter_by(dateTypeID=5).first().dateValue
notifications['email'] = session.query(Settings).filter_by(settingType=2).first().settingValue clean = False
today = datetime.date.today()
if notifications['text']: if nextClean == today or TESTING is True:
print('will send text') clean = True
if notifications['email']: else:
print('will send email') clean = False
print('checked') # 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() 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('/', methods=('GET', 'POST'))
@app.route('/index.html', methods=('GET', 'POST')) @app.route('/index.html', methods=('GET', 'POST'))
@@ -87,23 +115,25 @@ def index():
return redirect('install.html') return redirect('install.html')
# Init the dates dict # Init the dates dict
dates = {'plant': '', 'last': '', 'next': '', 'freq': ''} dates = {'plant': '', 'last': '', 'next': '', 'freq': '', 'lastClean': '', 'nextClean': '', 'cleanFreq': ''}
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)
alerts = {'text': False, 'email': False} 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 clicked the update button for dates, grab the new values and save them to the db. Then render the template
if request.method == 'POST': if request.method == 'POST':
dates['plant'] = request.form['plantDate'] dates['plant'] = request.form['plantDate']
dates['last'] = request.form['lastDate'] dates['last'] = request.form['lastDate']
dates['next'] = datetime.datetime.strptime(dates['last'], '%Y-%m-%d') + datetime.timedelta(days=dates['freq']) 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=1).update({Dates.dateValue: dates['plant']})
session.query(Dates).filter_by(dateTypeID=2).update({Dates.dateValue: dates['last']}) 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=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 # grab text message alert box. Set 'True' if checked or null if unchecked
if request.form.get('AlertText'): if request.form.get('AlertText'):
@@ -115,7 +145,7 @@ def index():
alerts['email'] = 'True' alerts['email'] = 'True'
else: else:
alerts['email'] = None 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=1).update({Settings.settingValue: alerts['text']})
session.query(Settings).filter_by(settingType=2).update({Settings.settingValue: alerts['email']}) 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['plant'] = session.query(Dates).filter_by(dateTypeID=1).first().dateValue
dates['last'] = session.query(Dates).filter_by(dateTypeID=2).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['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['text'] = session.query(Settings).filter_by(settingType=1).first().settingValue
alerts['email'] = session.query(Settings).filter_by(settingType=2).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=3, settingValue='14'))
session.add(Settings(settingType=4, settingValue=None)) session.add(Settings(settingType=4, settingValue=None))
session.add(Settings(settingType=5, settingValue=None)) session.add(Settings(settingType=5, settingValue=None))
session.add(Settings(settingType=6, settingValue='28'))
# Populate SettingsMetadata # Populate SettingsMetadata
session.add(SettingsMetadata(settingTypeID=1, settingTypeName='Text')) 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=3, settingTypeName='Feeding Frequency'))
session.add(SettingsMetadata(settingTypeID=4, settingTypeName='Alert Phone Number')) session.add(SettingsMetadata(settingTypeID=4, settingTypeName='Alert Phone Number'))
session.add(SettingsMetadata(settingTypeID=5, settingTypeName='Alert Email')) session.add(SettingsMetadata(settingTypeID=5, settingTypeName='Alert Email'))
session.add(SettingsMetadata(settingTypeID=6, settingTypeName='Cleaning Frequency'))
session.commit() session.commit()

59
sendNotifications.py Normal file
View File

@@ -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

View File

@@ -2,18 +2,23 @@
{% block content %} {% block content %}
<h1>Information</h1> <h1>Information</h1>
<form method="post"> <form method="post">
<h3>Feeding Information</h3>
<label>Plant Date</label> <label>Plant Date</label>
<input type="date" name="plantDate" value= {{ plant.plant }}> <input type="date" name="plantDate" value= {{ plant.plant }}>
<br> <br>
<label>Last Feed Date</label> <label>Last Feed Date</label>
<input type="date" name="lastDate" value= {{ plant.last }}> <input type="date" name="lastDate" value= {{ plant.last }}>
<br> <br>
<label>Next Feed Date</label> <!--<label>Next Feed Date</label>
<input type="date" name="nextDate" value= {{ plant.next }}> <input type="date" name="nextDate" value= {{ plant.next }}>-->
Next Feed Date: {{ plant.next }}
<br> <br>
Feed Frequency: {{ plant.freq }} days Feed Frequency: {{ plant.freq }} days
<h3>Cleaning Information</h3>
<label>Last Clean Date</label>
<input type="date" name="lastClean" value= {{ plant.lastClean }}>
<br> <br>
<br> Next Clean Date: {{ plant.nextClean }}
<h1>Alerts</h1> <h1>Alerts</h1>
<input type="checkbox" id="alert_text" name="AlertText" value={{ alerts.text }} {{ "checked" if alerts.text else "" }}> <input type="checkbox" id="alert_text" name="AlertText" value={{ alerts.text }} {{ "checked" if alerts.text else "" }}>
<label for="alert_text">Text Message</label> <label for="alert_text">Text Message</label>