commit to current

This commit is contained in:
Dan
2022-12-15 23:08:33 -05:00
parent 75f2a07722
commit 62df4359e7
7 changed files with 383 additions and 380 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
.idea/
venv/
__pycache__/

484
app.py
View File

@@ -1,242 +1,242 @@
from flask import Flask, render_template, request, flash, redirect from flask import Flask, render_template, request, flash, redirect
import datetime import datetime
import sendNotifications 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 # Set to True to simplify testing
TESTING = False TESTING = False
notificationHour = 10 notificationHour = 10
textSent = False textSent = False
emailSent = False emailSent = False
class Config: class Config:
SCHEDULER_API_ENABLED = True SCHEDULER_API_ENABLED = True
SCHEDULER_TIMEZONE = 'US/Eastern' SCHEDULER_TIMEZONE = 'US/Eastern'
app = Flask(__name__) app = Flask(__name__)
app.config['SECRET_KEY'] = 'fa6166b0218186fb852429060105aca18e0f979240be8ebf' app.config['SECRET_KEY'] = 'fa6166b0218186fb852429060105aca18e0f979240be8ebf'
app.config.from_object(Config()) app.config.from_object(Config())
scheduler = APScheduler() scheduler = APScheduler()
scheduler.init_app(app) scheduler.init_app(app)
# Needed below to access native APSchedule objects # Needed below to access native APSchedule objects
sched = scheduler.scheduler sched = scheduler.scheduler
Base = declarative_base() Base = declarative_base()
class Dates(Base): class Dates(Base):
__tablename__ = 'Dates' __tablename__ = 'Dates'
id = Column(Integer, primary_key=True, autoincrement=True) id = Column(Integer, primary_key=True, autoincrement=True)
dateTypeID = Column(Integer) dateTypeID = Column(Integer)
dateValue = Column(Date) dateValue = Column(Date)
class DatesMetadata(Base): class DatesMetadata(Base):
__tablename__ = 'DatesMetadata' __tablename__ = 'DatesMetadata'
id = Column(Integer, primary_key=True, autoincrement=True) id = Column(Integer, primary_key=True, autoincrement=True)
dateTypeID = Column(Integer) dateTypeID = Column(Integer)
DateTypeName = Column(String(50)) DateTypeName = Column(String(50))
class Settings(Base): class Settings(Base):
__tablename__ = 'Settings' __tablename__ = 'Settings'
id = Column(Integer, primary_key=True, autoincrement=True) id = Column(Integer, primary_key=True, autoincrement=True)
settingType = Column(Integer) settingType = Column(Integer)
settingValue = Column(String(50)) settingValue = Column(String(50))
class SettingsMetadata(Base): class SettingsMetadata(Base):
__tablename__ = 'SettingsMetadata' __tablename__ = 'SettingsMetadata'
id = Column(Integer, primary_key=True, autoincrement=True) id = Column(Integer, primary_key=True, autoincrement=True)
settingTypeID = Column(Integer) settingTypeID = Column(Integer)
settingTypeName = Column(String(50)) settingTypeName = Column(String(50))
engine = create_engine('mysql+pymysql://hydro:pRnCWH/M)dujdifi@db.dandembinski.com:3306/Hydro') engine = create_engine('mysql+pymysql://hydro:pRnCWH/M)dujdifi@db.dandembinski.com:3306/Hydro')
Dates.__table__.create(bind=engine, checkfirst=True) Dates.__table__.create(bind=engine, checkfirst=True)
Settings.__table__.create(bind=engine, checkfirst=True) Settings.__table__.create(bind=engine, checkfirst=True)
DatesMetadata.__table__.create(bind=engine, checkfirst=True) DatesMetadata.__table__.create(bind=engine, checkfirst=True)
SettingsMetadata.__table__.create(bind=engine, checkfirst=True) SettingsMetadata.__table__.create(bind=engine, checkfirst=True)
Session = sessionmaker(bind=engine) Session = sessionmaker(bind=engine)
@scheduler.task('cron', id='send_notifications', hour=notificationHour) @scheduler.task('cron', id='send_notifications', hour=notificationHour)
def Checknotifications(): def Checknotifications():
session = Session() session = Session()
global textSent global textSent
global emailSent global emailSent
nextFeed = session.query(Dates).filter_by(dateTypeID=3).first().dateValue nextFeed = session.query(Dates).filter_by(dateTypeID=3).first().dateValue
nextClean = session.query(Dates).filter_by(dateTypeID=5).first().dateValue nextClean = session.query(Dates).filter_by(dateTypeID=5).first().dateValue
clean = False clean = False
today = datetime.date.today() today = datetime.date.today()
if nextClean <= today or TESTING is True: if nextClean <= today or TESTING is True:
clean = True clean = True
else: else:
clean = False clean = False
# Check if notifications need to be sent out # Check if notifications need to be sent out
if nextFeed <= today or TESTING is True: 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 # Check what notifications should be sent out grab the grab relevant contact info and pass it to the appropriate
# notification method # notification method
notifications = {'text': session.query(Settings).filter_by(settingType=1).first().settingValue, notifications = {'text': session.query(Settings).filter_by(settingType=1).first().settingValue,
'email': session.query(Settings).filter_by(settingType=2).first().settingValue} 'email': session.query(Settings).filter_by(settingType=2).first().settingValue}
if notifications['text'] and textSent is False: if notifications['text'] and textSent is False:
contact = session.query(Settings).filter_by(settingType=4).first().settingValue contact = session.query(Settings).filter_by(settingType=4).first().settingValue
sendNotifications.sendText(contact, clean) sendNotifications.sendText(contact, clean)
textSent = True textSent = True
if notifications['email'] and emailSent is False: if notifications['email'] and emailSent is False:
contact = session.query(Settings).filter_by(settingType=5).first().settingValue contact = session.query(Settings).filter_by(settingType=5).first().settingValue
sendNotifications.sendEmail(contact, clean) sendNotifications.sendEmail(contact, clean)
print('sent any selected notifications') print('sent any selected notifications')
# print(today) # print(today)
# print(nextFeed) # print(nextFeed)
if TESTING is True: if TESTING is True:
resetNotifcations() resetNotifcations()
else: else:
print('Not time to Send') print('Not time to Send')
session.close() session.close()
@scheduler.task('cron', id='reset_notifications', hour=notificationHour+1) @scheduler.task('cron', id='reset_notifications', hour=notificationHour+1)
def resetNotifcations(): def resetNotifcations():
global textSent global textSent
global emailSent global emailSent
if textSent is True: if textSent is True:
textSent = False textSent = False
if emailSent is True: if emailSent is True:
emailSent = False emailSent = False
return return
scheduler.start() scheduler.start()
# If in testing mode reschedule the notification check to run every minute # If in testing mode reschedule the notification check to run every minute
if TESTING is True: if TESTING is True:
sched.reschedule_job('send_notifications', trigger='cron', minute='*') sched.reschedule_job('send_notifications', trigger='cron', minute='*')
print('Sending notifications every 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'))
def index(): def index():
session = Session() session = Session()
installCheck = session.query(Dates).first() is None installCheck = session.query(Dates).first() is None
if installCheck is True: if installCheck is True:
# session.close() # session.close()
return redirect('install.html') return redirect('install.html')
# Init the dates dict # Init the dates dict
dates = {'plant': '', 'last': '', 'next': '', 'freq': '', 'lastClean': '', 'nextClean': '', 'cleanFreq': ''} dates = {'plant': '', 'last': '', 'next': '', 'freq': '', 'lastClean': '', 'nextClean': '', 'cleanFreq': ''}
alerts = {'text': False, 'email': False} alerts = {'text': False, 'email': False}
# Get the feeding frequency and cleaning frequency set them to ints # Get the feeding frequency and cleaning frequency set them to ints
dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue) dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue)
dates['cleanFreq'] = int(session.query(Settings).filter_by(settingType=6).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['lastClean'] = request.form['lastClean']
dates['cleanFreq'] = datetime.datetime.strptime(dates['lastClean'], '%Y-%m-%d') + datetime.timedelta(days=dates['cleanFreq']) 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=4).update({Dates.dateValue: dates['lastClean']})
session.query(Dates).filter_by(dateTypeID=5).update({Dates.dateValue: dates['cleanFreq']}) 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'):
alerts['text'] = 'True' alerts['text'] = 'True'
else: else:
alerts['text'] = None alerts['text'] = None
# grab email message alert box. Set 'True' if checked or null if unchecked # grab email message alert box. Set 'True' if checked or null if unchecked
if request.form.get('AlertEmail'): if request.form.get('AlertEmail'):
alerts['email'] = 'True' alerts['email'] = 'True'
else: else:
alerts['email'] = None alerts['email'] = None
# Update the alert settings to the database # 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']})
session.commit() session.commit()
# return render_template("index.html", plant=dates, alerts=alerts) # return render_template("index.html", plant=dates, alerts=alerts)
return redirect('index.html') return redirect('index.html')
# If regular page load, grab all the dates from the db and render the template # If regular page load, grab all the dates from the db and render the template
else: else:
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['lastClean'] = session.query(Dates).filter_by(dateTypeID=4).first().dateValue
dates['nextClean'] = session.query(Dates).filter_by(dateTypeID=5).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
return render_template("index.html", plant=dates, alerts=alerts) return render_template("index.html", plant=dates, alerts=alerts)
@app.route('/updateFeed') @app.route('/updateFeed')
def updateFeed(): def updateFeed():
session = Session() session = Session()
dates = {'plant': '', 'last': '', 'next': '', 'freq': ''} dates = {'plant': '', 'last': '', 'next': '', 'freq': ''}
dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue) dates['freq'] = int(session.query(Settings).filter_by(settingType=3).first().settingValue)
dates['last'] = datetime.date.today() dates['last'] = datetime.date.today()
dates['next'] = dates['last'] + datetime.timedelta(days=dates['freq']) dates['next'] = dates['last'] + datetime.timedelta(days=dates['freq'])
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.commit() session.commit()
session.close() session.close()
return redirect('/index.html') return redirect('/index.html')
@app.route('/install.html') @app.route('/install.html')
def install(): def install():
session = Session() session = Session()
populateDate = datetime.date.today() populateDate = datetime.date.today()
# Populate Dates Table # Populate Dates Table
session.add(Dates(dateTypeID=1, dateValue=populateDate)) session.add(Dates(dateTypeID=1, dateValue=populateDate))
session.add(Dates(dateTypeID=2, dateValue=populateDate)) session.add(Dates(dateTypeID=2, dateValue=populateDate))
session.add(Dates(dateTypeID=3, dateValue=populateDate)) session.add(Dates(dateTypeID=3, dateValue=populateDate))
# Populate DatesMetadata # Populate DatesMetadata
session.add(DatesMetadata(dateTypeID=1, DateTypeName='Plant Date')) session.add(DatesMetadata(dateTypeID=1, DateTypeName='Plant Date'))
session.add(DatesMetadata(dateTypeID=2, DateTypeName='Last Feeding Date')) session.add(DatesMetadata(dateTypeID=2, DateTypeName='Last Feeding Date'))
session.add(DatesMetadata(dateTypeID=3, DateTypeName='Next Feeding Date')) session.add(DatesMetadata(dateTypeID=3, DateTypeName='Next Feeding Date'))
# Populate Settings # Populate Settings
session.add(Settings(settingType=1, settingValue='False')) session.add(Settings(settingType=1, settingValue='False'))
session.add(Settings(settingType=2, settingValue='False')) session.add(Settings(settingType=2, settingValue='False'))
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')) 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'))
session.add(SettingsMetadata(settingTypeID=2, settingTypeName='Email')) session.add(SettingsMetadata(settingTypeID=2, settingTypeName='Email'))
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.add(SettingsMetadata(settingTypeID=6, settingTypeName='Cleaning Frequency'))
session.commit() session.commit()
return redirect('index.html') return redirect('index.html')
if __name__ == '__main__': if __name__ == '__main__':
serve(app, host='0.0.0.0', port=8000) serve(app, host='0.0.0.0', port=8000)

View File

@@ -1,26 +1,26 @@
APScheduler==3.8.1 APScheduler==3.8.1
certifi==2021.10.8 certifi==2021.10.8
charset-normalizer==2.0.11 charset-normalizer==2.0.11
click==8.0.3 click==8.0.3
colorama==0.4.4 colorama==0.4.4
Flask==2.0.2 Flask==2.0.2
Flask-APScheduler==1.12.3 Flask-APScheduler==1.12.3
greenlet==1.1.2 greenlet==1.1.2
gunicorn==20.1.0 gunicorn==20.1.0
idna==3.3 idna==3.3
itsdangerous==2.0.1 itsdangerous==2.0.1
Jinja2==3.0.3 Jinja2==3.0.3
MarkupSafe==2.0.1 MarkupSafe==2.0.1
PyJWT==2.3.0 PyJWT==2.3.0
PyMySQL==1.0.2 PyMySQL==1.0.2
python-dateutil==2.8.2 python-dateutil==2.8.2
pytz==2021.3 pytz==2021.3
pytz-deprecation-shim==0.1.0.post0 pytz-deprecation-shim==0.1.0.post0
requests==2.27.1 requests==2.27.1
six==1.16.0 six==1.16.0
SQLAlchemy==1.4.30 SQLAlchemy==1.4.30
twilio==7.6.0 twilio==7.6.0
tzdata==2021.5 tzdata==2021.5
tzlocal==4.1 tzlocal==4.1
urllib3==1.26.8 urllib3==1.26.8
Werkzeug==2.0.2 Werkzeug==2.0.2

View File

@@ -1,59 +1,59 @@
from twilio.rest import Client from twilio.rest import Client
from smtplib import SMTP from smtplib import SMTP
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.base import MIMEBase from email.mime.base import MIMEBase
# Twilio Account Setup # Twilio Account Setup
account_sid = 'AC051785f6dd5a93184641d01103eb8cd4' account_sid = 'AC051785f6dd5a93184641d01103eb8cd4'
auth_token = 'd40c831e56785afaa9294fd3c5a88e6e' auth_token = 'd40c831e56785afaa9294fd3c5a88e6e'
client = Client(account_sid, auth_token) client = Client(account_sid, auth_token)
# Email Account Setup # Email Account Setup
smtp_server = 'in-v3.mailjet.com' smtp_server = 'in-v3.mailjet.com'
smtp_port = 587 smtp_port = 587
def sendText(contact, clean): def sendText(contact, clean):
if clean is True: if clean is True:
cleanMsg = 'Feed the Hydroponics. It also needs to be cleaned today' cleanMsg = 'Feed the Hydroponics. It also needs to be cleaned today'
else: else:
cleanMsg = 'Feed the Hydroponics.' cleanMsg = 'Feed the Hydroponics.'
message = client.messages.create( message = client.messages.create(
messaging_service_sid='MG864145600a43493122488250262ccbc9', messaging_service_sid='MG864145600a43493122488250262ccbc9',
body=cleanMsg, body=cleanMsg,
to=contact to=contact
) )
return return
def sendEmail(contact, clean): def sendEmail(contact, clean):
from_addr = 'Hydro@dandembinski.com' from_addr = 'Hydro@dandembinski.com'
smtp = SMTP() smtp = SMTP()
smtp.connect(smtp_server, smtp_port) smtp.connect(smtp_server, smtp_port)
smtp.login('bef546c3019739fff8a2dbbfc26ec74a', 'dbe2b63a3f1fa5e4f00217c2784a8055') smtp.login('bef546c3019739fff8a2dbbfc26ec74a', 'dbe2b63a3f1fa5e4f00217c2784a8055')
if clean is True: if clean is True:
cleanMsg = 'Feed the Hydroponics. It also needs to be cleaned today' cleanMsg = 'Feed the Hydroponics. It also needs to be cleaned today'
else: else:
cleanMsg = 'Feed the Hydroponics.' cleanMsg = 'Feed the Hydroponics.'
bodyHTML = MIMEText(cleanMsg, "html") bodyHTML = MIMEText(cleanMsg, "html")
msg = MIMEMultipart() msg = MIMEMultipart()
msg['Subject'] = 'Feed Hydroponics' msg['Subject'] = 'Feed Hydroponics'
msg['To'] = contact msg['To'] = contact
msg['From'] = from_addr msg['From'] = from_addr
msg.add_header('Content-Type', 'text/html') msg.add_header('Content-Type', 'text/html')
msg.attach(bodyHTML) msg.attach(bodyHTML)
try: try:
smtp.send_message(msg) smtp.send_message(msg)
except Exception as e: except Exception as e:
print(e) print(e)
return return

View File

@@ -1,3 +1,3 @@
function updateFeed() { function updateFeed() {
fetch('/updateFeed') fetch('/updateFeed')
} }

View File

@@ -1,20 +1,20 @@
<html> <html>
<head> <head>
<title>Hydro</title> <title>Hydro</title>
</head> </head>
<body> <body>
<script type="text/javascript" src="/static/scripts.js"></script> <script type="text/javascript" src="/static/scripts.js"></script>
<div>Hydro: <a href="index.html">home</a></div> <div>Hydro: <a href="index.html">home</a></div>
<br> <br>
{% with messages = get_flashed_messages() %} {% with messages = get_flashed_messages() %}
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}
{{ message }} {{ message }}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<br> <br>
{% block content %}{% endblock %} {% block content %}{% endblock %}
</body> </body>
</html> </html>

View File

@@ -1,33 +1,33 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<h1>Information</h1> <h1>Information</h1>
<form method="post"> <form method="post">
<h3>Feeding Information</h3> <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 }} Next Feed Date: {{ plant.next }}
<br> <br>
Feed Frequency: {{ plant.freq }} days Feed Frequency: {{ plant.freq }} days
<h3>Cleaning Information</h3> <h3>Cleaning Information</h3>
<label>Last Clean Date</label> <label>Last Clean Date</label>
<input type="date" name="lastClean" value= {{ plant.lastClean }}> <input type="date" name="lastClean" value= {{ plant.lastClean }}>
<br> <br>
Next Clean Date: {{ plant.nextClean }} Next Clean Date: {{ plant.nextClean }}
<br> <br>
Cleaning Frequency: {{ plant.cleanFreq }} days Cleaning Frequency: {{ plant.cleanFreq }} days
<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>
<input type="checkbox" id="alert_email" name="AlertEmail" value={{ alerts.email }} {{ "checked" if alerts.email else "" }}> <input type="checkbox" id="alert_email" name="AlertEmail" value={{ alerts.email }} {{ "checked" if alerts.email else "" }}>
<label for="alert_email">Email</label><br> <label for="alert_email">Email</label><br>
<input type="submit" id="DateSubmitForm" name="DateSubmitForm" value="Save"> <input type="submit" id="DateSubmitForm" name="DateSubmitForm" value="Save">
</form> </form>
<button class=button onclick="updateFeed()">Update Feed</button> <button class=button onclick="updateFeed()">Update Feed</button>
{% endblock %} {% endblock %}