diff --git a/.gitignore b/.gitignore
index 56c1acd..c770f86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
*__pycache__*
.venv*
-.env
+.env*
mongo_data/*
diff --git a/base.Dockerfile b/base.Dockerfile
index 43f727a..9534f70 100644
--- a/base.Dockerfile
+++ b/base.Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.10 as pool_base_image
+FROM python:3.10 AS pool_base_image
WORKDIR /pool_data
@@ -9,4 +9,3 @@ RUN apt-get update -y && apt-get upgrade -y && apt-get install -y libsasl2-dev p
RUN pip install --upgrade pip
RUN pip --default-timeout=1000 install -r requirements.txt
-
diff --git a/docker-compose.yml b/docker-compose.yml
index eeb547c..892a27c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,7 +8,7 @@ services:
context: .
dockerfile: flask.Dockerfile
volumes:
- - ./src/flask:/pool_data_web/src/flask
+ - ./src/flask:/pool_data/src/flask
ports:
- "80:80"
- "5000:5000"
diff --git a/flask.Dockerfile b/flask.Dockerfile
index bc06c42..38e7fb8 100644
--- a/flask.Dockerfile
+++ b/flask.Dockerfile
@@ -1,4 +1,4 @@
-FROM pool_base_image as flask
+FROM pool_base_image AS flask
COPY requirements.txt .
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..a578942
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,3 @@
+[tool.pyright]
+venvPath = "."
+venv = ".venv"
diff --git a/requirements.txt b/requirements.txt
index e95fd0e..aaf30fa 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,3 +6,4 @@ click
Flask-WTF
bootstrap-flask
waitress
+bokeh
diff --git a/src/flask/chart_test.html b/src/flask/chart_test.html
new file mode 100644
index 0000000..0ce9862
--- /dev/null
+++ b/src/flask/chart_test.html
@@ -0,0 +1,61 @@
+
+
+
+
+ Bokeh Plot
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/flask/chart_test.py b/src/flask/chart_test.py
new file mode 100644
index 0000000..d30feaa
--- /dev/null
+++ b/src/flask/chart_test.py
@@ -0,0 +1,17 @@
+from bokeh.models.layouts import HBox
+from bokeh.plotting import column
+from charts import PoolCharts
+from bokeh.io import output_file, show
+from bokeh.layouts import row
+
+output_file("static/data_plot.html")
+
+chart = PoolCharts.PoolCharts()
+
+ph = chart.line_chart("Pool PH", "ph", 50)
+
+total_chlorine = chart.line_chart("Pool Total Chlorine", "total_chlorine", 50)
+
+free_chlorine = chart.line_chart("Pool Free Chlorine", "free_chlorine", 50)
+
+show(column(ph, total_chlorine, free_chlorine))
diff --git a/src/flask/charts/PoolCharts.py b/src/flask/charts/PoolCharts.py
new file mode 100644
index 0000000..a15cd86
--- /dev/null
+++ b/src/flask/charts/PoolCharts.py
@@ -0,0 +1,49 @@
+import sys
+
+from bokeh.models.widgets import DataCube
+from bokeh.plotting import figure
+
+from mongo.get_conn import db_conn
+
+class PoolCharts():
+ def __init__(self):
+ self.db = db_conn()
+
+
+ def line_chart(self, title, field, limit):
+ data = self.db.pool_db
+ data = data.find({}).sort("date", -1).limit(limit)
+ dates = []
+ data_list = []
+ date_count = {}
+ for record in data:
+ if field in record and record[field] != "None":
+ if record["date"] not in dates:
+ print("new date record")
+ dates.append(record["date"])
+ data_list.append(float(record[field]))
+ print (dates)
+ print (data_list)
+ else:
+ if record["date"] in date_count:
+ date_count[record["date"]] += 1
+ else:
+ date_count[record["date"]] = 2
+ print(len(data_list))
+ current_data = data_list[len(data_list) - 1]
+ data_list[len(data_list) - 1] = (float(record[field]) + current_data) / date_count[record["date"]]
+
+ print(dates)
+ print(data_list)
+
+ p = figure(x_range=dates, height=250, title=title,
+ toolbar_location=None, tools="")
+
+ p.line(x=dates, y=data_list)
+
+ p.xgrid.grid_line_color = None
+ if not data_list:
+ p.y_range.start = 0
+ else:
+ p.y_range.start = round(min(data_list) - 1)
+ return p
diff --git a/src/flask/charts/__init__.py b/src/flask/charts/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/flask/mongo/query_db.py b/src/flask/mongo/query_db.py
index c8aa476..17c1491 100644
--- a/src/flask/mongo/query_db.py
+++ b/src/flask/mongo/query_db.py
@@ -23,7 +23,7 @@ class pool_query:
queried record
"""
query = { "test_user" : f"{test_user}", "date" : f"{date}"}
- record = self.db.real_db.find_one(query)
+ record = self.db.pool_db.find_one(query)
if record:
self.existing_record = record
return True
diff --git a/src/flask/pool_data.py b/src/flask/pool_data.py
index 8f31be3..3c9e2db 100644
--- a/src/flask/pool_data.py
+++ b/src/flask/pool_data.py
@@ -1,3 +1,4 @@
+from bokeh.core.enums import SpatialUnitsType
import mongo.build_db as pool_database
import mongo.query_db as pool_database_query
@@ -5,8 +6,13 @@ from flask import Flask, render_template, request, jsonify, redirect, session
from flask_wtf import FlaskForm, CSRFProtect
from flask_bootstrap import Bootstrap5
from wtforms import StringField, SubmitField, DateField, IntegerField, PasswordField, DecimalField, RadioField, TextAreaField
-from wtforms.validators import DataRequired, Length
+from wtforms.validators import DataRequired, Length, Optional
from waitress import serve
+from bokeh.models.layouts import HBox
+from bokeh.plotting import column
+from charts import PoolCharts
+from bokeh.io import output_file, show
+from bokeh.layouts import row
app = Flask(__name__)
app.secret_key = 'testsecret' #this value will change
@@ -14,6 +20,21 @@ app.secret_key = 'testsecret' #this value will change
bootstrap = Bootstrap5(app)
csrf = CSRFProtect(app)
+# used to configure the bokeh plot for graphs
+output_file("/pool_data/src/flask/static/data_plot.html")
+
+def create_graphs():
+ chart = PoolCharts.PoolCharts()
+ ph = chart.line_chart("Pool PH", "ph", 30)
+ total_chlorine = chart.line_chart("Pool Total Chlorine", "total_chlorine", 30)
+ free_chlorine = chart.line_chart("Pool Free Chlorine", "free_chlorine", 30)
+ alkalinity = chart.line_chart("Alkalinity", "alkalinity", 30)
+ salt = chart.line_chart("Salt", "salt", 30)
+ temp = chart.line_chart("Temperature", "temp", 30)
+ hardness = chart.line_chart("Hardness", "hardness", 30)
+ stabiliser = chart.line_chart("Stabiliser", "stabiliser", 30)
+ show(row(column(ph, total_chlorine, free_chlorine, temp), column(salt, alkalinity, hardness, stabiliser)))
+
class userForm(FlaskForm):
username = StringField("User Name?", validators=[DataRequired()])
@@ -21,20 +42,20 @@ class userForm(FlaskForm):
submit = SubmitField("Letsa GO!")
class dataForm(FlaskForm):
- test_user = RadioField("Tester:",
+ test_user = RadioField("Tester:",
choices=[("Isabella"), ("Heather"), ("Ariah")])
Date = DateField("Date:")
- free_chlorine = IntegerField("Free Chlorine:")
- total_chlorine = IntegerField("Total Chlorine:")
- alkalinity = DecimalField("Alkalinity:")
- PH = DecimalField("PH:")
- hardness = IntegerField("Hardness")
- stabiliser = IntegerField("CYA - Stabliser")
- salt = IntegerField("Salt:")
- temp = DecimalField("Water Temperature")
- comment = TextAreaField("Any Comments?")
+ free_chlorine = IntegerField("Free Chlorine:", validators=[Optional()])
+ total_chlorine = IntegerField("Total Chlorine:", validators=[Optional()])
+ alkalinity = DecimalField("Alkalinity:", validators=[Optional()])
+ PH = DecimalField("PH:", validators=[Optional()])
+ hardness = IntegerField("Hardness", validators=[Optional()])
+ stabiliser = IntegerField("CYA - Stabliser", validators=[Optional()])
+ salt = IntegerField("Salt:", validators=[Optional()])
+ temp = DecimalField("Water Temperature", validators=[Optional()])
+ comment = TextAreaField("Any Comments?", validators=[Optional()])
submit = SubmitField("Write it, Write it REAAAAAAL GOOOD")
-
+
@app.route("/", methods=["GET","POST"])
def index():
form = userForm()
@@ -54,7 +75,7 @@ def index():
def updater():
if 'logged_in' not in session:
return redirect("/")
-
+ create_graphs()
query_db = pool_database_query.pool_query()
query = query_db.get_top(10, "ph")
form = dataForm()
@@ -81,15 +102,15 @@ def updater():
if database.existing_record[field] != new_record[field]:
database.update_re_record(database.existing_record["_id"], field, new_record[field])
else:
- database.create_re_record(new_record["ph"], new_record["total_chlorine"], new_record["free_chlorine"],
+ database.create_re_record(new_record["ph"], new_record["total_chlorine"], new_record["free_chlorine"],
new_record["alkalinity"], new_record["date"], new_record["test_user"],
- new_record["temp"], new_record["hardness"], new_record["stabiliser"],
+ new_record["temp"], new_record["hardness"], new_record["stabiliser"],
new_record["salt"], new_record["comment"])
- return render_template("updater.html", list=query, form=form)
+ return render_template("updater.html", list=query, form=form, success=True, updater_name = new_record["test_user"])
else:
- return render_template("updater.html", list=query, form=form)
+ return render_template("updater.html", list=query, form=form, sucess=False)
@app.route("/update_db", methods=["POST"])
def pool_data_update():
@@ -102,9 +123,9 @@ def pool_data_update():
if database.existing_record[field] != new_record[field]:
database.update_re_record(database.existing_record["_id"], field, new_record[field])
else:
- database.create_re_record(new_record["ph"], new_record["total_chlorine"], new_record["free_chlorine"],
+ database.create_re_record(new_record["ph"], new_record["total_chlorine"], new_record["free_chlorine"],
new_record["alkalinity"], new_record["date"], new_record["test_user"],
- new_record["temp"], new_record["hardness"], new_record["stabiliser"],
+ new_record["temp"], new_record["hardness"], new_record["stabiliser"],
new_record["salt"], new_record["comment"])
@@ -117,4 +138,3 @@ def user_detail(id):
if __name__ == '__main__':
#app.run(host='0.0.0.0')
serve(app, host='0.0.0.0', port=5000, url_scheme='https')
-
diff --git a/src/flask/static/data_plot.html b/src/flask/static/data_plot.html
new file mode 100644
index 0000000..d5d1fd7
--- /dev/null
+++ b/src/flask/static/data_plot.html
@@ -0,0 +1,61 @@
+
+
+
+
+ Bokeh Plot
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/flask/templates/base.html b/src/flask/templates/base.html
index be59d47..f619e1c 100644
--- a/src/flask/templates/base.html
+++ b/src/flask/templates/base.html
@@ -1,30 +1,26 @@
-
+
-
-
-
+
+
+
-
- {% block title %}
- Let there Be Pool Data
- {% endblock %}
-
+ {% block title %} Let there Be Pool Data {% endblock %}
- {{ bootstrap.load_css() }}
+ {{ bootstrap.load_css() }}
-
-
-
-
-{% block content %}
-{% endblock %}
+ {% block content %} {% endblock %}
-
-
-{{ bootstrap.load_js() }}
-
+
+ {{ bootstrap.load_js() }}
+
diff --git a/src/flask/templates/updater.html b/src/flask/templates/updater.html
index b9380ed..8c8c088 100644
--- a/src/flask/templates/updater.html
+++ b/src/flask/templates/updater.html
@@ -5,7 +5,6 @@
Data Input
{% endblock %}
{% block content %}
-
+
+
|
-
-
+
+
+
{% endblock %}
diff --git a/start_env b/start_env
index 4657523..24424ac 100755
--- a/start_env
+++ b/start_env
@@ -1,4 +1,4 @@
-# /bin/bash
+ou /bin/bash
source .venv/bin/activate
source .env