Commit 1254e606 authored by Kristian Tan's avatar Kristian Tan

Merge branch 'master' of github.com:KristianTan/IoTSmartMeter

parents a217470b 824b3aad
from .daily_usage import DailyUsage
\ No newline at end of file
from flask import Flask, render_template
import RPi.GPIO as GPIO
from flask_sqlalchemy import SQLAlchemy
from .daily_usage import DailyUsage
import os
from datetime import datetime, date, timedelta
# from daily_usage import DailyUsage
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///energyUsage'
db = SQLAlchemy(app)
SQLAlchemy.create_all()
db.create_all()
os.environ['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///energyUsage'
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['SQLALCHEMY_DATABASE_URI']
# To suppress warnings
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
test = DailyUsage("12/11/2019", 5)
db.session.add(test)
db.session.commit()
db = SQLAlchemy(app)
# TODO: Move this into daily_usage class file
class DailyUsage(db.Model):
__tablename__ = 'daily_usage'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
date = db.Column(db.DateTime, unique=True, nullable=False)
kwhUsed = db.Column(db.Float, unique=False)
def __init__(self, date, kwhUsed):
self.date = date
self.kwhUsed = kwhUsed
def __repr__(self):
return '<DailyUsage %r, %r, %r>' % (self.id, self.date, self.kwhUsed)
db.create_all()
# TODO: be able to query db by date
daily_total = 0
latest_entry = db.session.query(DailyUsage).order_by(DailyUsage.id.desc()).first()
if latest_entry:
latest_entry_date = date(latest_entry.date.year, latest_entry.date.month, latest_entry.date.day)
if latest_entry_date == datetime.today().date():
daily_total = format(latest_entry.kwhUsed, '.7f')
todays_cost = format(float(daily_total) * 0.1622, '0.5f')
# Create dictionary to store pin info
pins = {
25: {'name': 'Light', 'state': GPIO.LOW}
25: {'name': 'Light', 'state': GPIO.LOW, 'on_time': None, 'on_date': None, 'Wattage': 15}
}
......@@ -35,40 +66,75 @@ def main():
# Set the template data for the HTML template
template_data = {
'pins': pins
'pins': pins,
'daily_total': daily_total,
'todays_cost': todays_cost
}
return render_template('main.html', **template_data)
@app.route("/<change_pin>")
@app.route("/toggle/<change_pin>")
def toggle_pin(change_pin):
# TODO: change_pin is somethimes favicon.co for some reason? Fix
if change_pin == 'favicon.ico':
pass
change_pin = int(change_pin)
device_name = pins[change_pin]['name']
# Toggle the selected pin
GPIO.output(change_pin, not GPIO.input(change_pin))
message = "Turned " + device_name
if GPIO.input(change_pin) == 0:
message += " off."
if pins[change_pin]['on_time'] is not None:
create_entry(change_pin)
else:
message += " on."
pins[change_pin]['on_time'] = datetime.now()
pins[change_pin]['on_date'] = date.today()
for pin in pins:
pins[pin]['state'] = GPIO.input(pin)
latest_entry = db.session.query(DailyUsage).order_by(DailyUsage.id.desc()).first()
if latest_entry:
latest_entry_date = date(latest_entry.date.year, latest_entry.date.month, latest_entry.date.day)
if latest_entry_date == datetime.today().date():
daily_total = format(latest_entry.kwhUsed, '.7f')
else:
daily_total = 0
todays_cost = format(float(daily_total) * 0.1622, '0.5f')
template_data = {
'message': message,
'pins': pins
'pins': pins,
'daily_total': daily_total,
'todays_cost': todays_cost
}
return render_template('main.html', **template_data)
def create_entry(change_pin):
latest_entry = db.session.query(DailyUsage).order_by(DailyUsage.id.desc()).first()
start_time = pins[change_pin]['on_time']
# Get the elapsed time and strip away milliseconds
elapsed = int((datetime.now() - start_time).total_seconds())
start_date = pins[change_pin]['on_date']
# Formula to calculate kWh based on time and wattage
kwh = pins[change_pin]['Wattage'] * (elapsed / 3600) / 1000
# If there is already an entry for today, update on time
# if latest_entry:
if latest_entry:
latest_entry_date = date(latest_entry.date.year, latest_entry.date.month, latest_entry.date.day)
if latest_entry_date == start_date:
latest_entry.kwhUsed += kwh
else:
# If no entry for today, make one
entry = DailyUsage(date=start_date, kwhUsed=kwh)
db.session.add(entry)
db.session.commit()
pins[change_pin]['on_time'] = None
pins[change_pin]['on_date'] = None
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8090)
from .app import db
from app import db
class DailyUsage(db.Model):
......@@ -7,4 +7,4 @@ class DailyUsage(db.Model):
hours = db.Column(db.Integer(120), unique=False)
def __repr__(self):
return '<User %r>' % self.username
\ No newline at end of file
return '<DailyUsage %r>' % self.id
......@@ -16,17 +16,14 @@
{% for pin in pins %}
<p>{{ pins[pin].name }} :
{% if pins[pin].state == true %}
(<a href="/{{pin}}">turn off</a>)
(<a href="/toggle/{{pin}}">turn off</a>)
{% else %}
(<a href="/{{pin}}">turn on</a>)
(<a href="/toggle/{{pin}}">turn on</a>)
{% endif %}
</p>
{% endfor %}
{# {% if message %}#}
{# <h2>{{ message }}</h2>#}
{# {% endif %}#}
</div>
<div class="smart_meter">
......@@ -39,9 +36,9 @@
{% endfor %}
</p>
{# Implement some way to display "No devices" message if none are in use#}
<p> Used today:
</p>
<p> Total energy used today: {{ daily_total }} kWh.</p>
<p> Total cost of today's energy usage: £{{ todays_cost }}</p>
</div>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment