add: fridges view, fridge+sensor class, plot function, generator for test data
This commit is contained in:
15
app/fridge.py
Normal file
15
app/fridge.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class Fridge:
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name.decode('utf-8')
|
||||||
|
self.sensors = list()
|
||||||
|
|
||||||
|
def add_sensor(self, sensor):
|
||||||
|
self.sensors.append(sensor)
|
||||||
|
|
||||||
|
|
||||||
|
class Sensor:
|
||||||
|
|
||||||
|
def __init__(self, name, sensorid):
|
||||||
|
self.name = name.decode('utf-8')
|
||||||
|
self.id = sensorid
|
||||||
26
app/gen_test_data_temperature.py
Normal file
26
app/gen_test_data_temperature.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import numpy as np
|
||||||
|
import datetime as dt
|
||||||
|
import pandas as pa
|
||||||
|
import ipdb
|
||||||
|
testdata = np.empty((14400, 7), dtype=object)
|
||||||
|
|
||||||
|
#ipdb.set_trace()
|
||||||
|
|
||||||
|
for n, line in enumerate(reversed(testdata)):
|
||||||
|
a = (dt.datetime.now() - dt.timedelta(seconds=(300*n)))
|
||||||
|
line[0] = a
|
||||||
|
line[1] = np.sin(2.0 * np.pi *20.0 / 14400 * n) * 5 + np.sin(2.0 * np.pi * 2.0 / 14400 * n) * 1.4 + 10
|
||||||
|
line[2] = np.sin(2.0 * np.pi *20.0 / 14400 * n) * 4 + np.sin(2.0 * np.pi * 2.0 / 14400 * n) * 1.4 + 13
|
||||||
|
line[3] = np.sin(2.0 * np.pi *20.0 / 14400 * n) * 3 + np.sin(2.0 * np.pi * 2.0 / 14400 * n) * 1.4 + 15
|
||||||
|
line[4] = np.sin(2.0 * np.pi *30.0 / 14400 * n) * 5 + np.sin(2.0 * np.pi * 3.5 / 14400 * n) * 1 + 10
|
||||||
|
line[5] = np.sin(2.0 * np.pi *30.0 / 14400 * n) * 4 + np.sin(2.0 * np.pi * 3.5 / 14400 * n) * 1 + 13
|
||||||
|
line[6] = np.sin(2.0 * np.pi *30.0 / 14400 * n) * 3 + np.sin(2.0 * np.pi * 3.5 / 14400 * n) * 1 + 15
|
||||||
|
|
||||||
|
pdata = pa.DataFrame.from_records(testdata,columns=("time","1","2","3","4","5","6"))
|
||||||
|
print pdata
|
||||||
|
|
||||||
|
pdata.to_csv("static/testdata.csv", index=False)
|
||||||
|
#np.savetxt("static/testdata.csv", testdata)
|
||||||
|
|
||||||
|
readdata = pa.read_csv("static/testdata.csv")
|
||||||
|
print readdata
|
||||||
93
app/plot.py
93
app/plot.py
@@ -1,12 +1,16 @@
|
|||||||
#import matplotlib #speed?
|
#import matplotlib #speed?
|
||||||
#matplotlib.use('GTKAgg')
|
#matplotlib.use('GTKAgg')
|
||||||
|
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
|
from matplotlib import units
|
||||||
from matplotlib.dates import WeekdayLocator, DayLocator, HourLocator, DateFormatter, drange, MONDAY
|
from matplotlib.dates import WeekdayLocator, DayLocator, HourLocator, DateFormatter, drange, MONDAY
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from user import User
|
from user import User
|
||||||
from database import *
|
from database import *
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
|
import pandas as pd
|
||||||
|
import ipdb
|
||||||
|
import logging
|
||||||
|
|
||||||
def plot_all_thread(user=None):
|
def plot_all_thread(user=None):
|
||||||
if user is not None:
|
if user is not None:
|
||||||
@@ -21,21 +25,17 @@ def plot_all(user=None):
|
|||||||
plot_total(user)
|
plot_total(user)
|
||||||
plot_total()
|
plot_total()
|
||||||
plot_list(4)
|
plot_list(4)
|
||||||
print 'plot_all'
|
logging.info('plot_all')
|
||||||
|
|
||||||
|
|
||||||
def plot_total(user=None):
|
def plot_total(user=None):
|
||||||
print "start plot_total " + str(datetime.datetime.now())
|
logging.info("start plot_total")
|
||||||
print 'plot_total'
|
|
||||||
today = datetime.date.today()
|
today = datetime.date.today()
|
||||||
delta = datetime.timedelta(days=1)
|
delta = datetime.timedelta(days=1)
|
||||||
begin = today - datetime.timedelta(weeks=2)
|
begin = today - datetime.timedelta(weeks=2)
|
||||||
dates = drange(begin, today + delta, delta)
|
dates = drange(begin, today + delta, delta)
|
||||||
|
|
||||||
#print begin
|
|
||||||
#print today
|
|
||||||
#print dates
|
|
||||||
|
|
||||||
products = get_products()
|
products = get_products()
|
||||||
allconsumptions = [[0 for x in range(len(dates))] for product in products]
|
allconsumptions = [[0 for x in range(len(dates))] for product in products]
|
||||||
|
|
||||||
@@ -94,17 +94,84 @@ def plot_total(user=None):
|
|||||||
fils = "app/static/total%03d.png" % user.id
|
fils = "app/static/total%03d.png" % user.id
|
||||||
fill = "app/static/total%03d_big.png" % user.id
|
fill = "app/static/total%03d_big.png" % user.id
|
||||||
plt.title(tit)
|
plt.title(tit)
|
||||||
print "plot plot_total " + str(datetime.datetime.now())
|
logging.info("plot plot_total " + str(datetime.datetime.now()))
|
||||||
#480x320
|
#480x320
|
||||||
fig.set_size_inches(4.8, 3.2)
|
fig.set_size_inches(4.8, 3.2)
|
||||||
plt.savefig(fils, dpi=100)
|
plt.savefig(fils, dpi=100)
|
||||||
print "end plot_total " + str(datetime.datetime.now())
|
logging.info("end plot_total " + str(datetime.datetime.now()))
|
||||||
#fig.set_size_inches(4.8, 3.2)
|
#fig.set_size_inches(4.8, 3.2)
|
||||||
#plt.savefig(fill, dpi=400)
|
#plt.savefig(fill, dpi=400)
|
||||||
|
|
||||||
|
|
||||||
|
def plot_log(days, logfiles):
|
||||||
|
today = datetime.date.today()
|
||||||
|
delta = datetime.timedelta(days=1)
|
||||||
|
begin = today - datetime.timedelta(days=days)
|
||||||
|
dates = drange(begin, today + delta, delta)
|
||||||
|
|
||||||
|
#print begin
|
||||||
|
#print today
|
||||||
|
#print dates
|
||||||
|
|
||||||
|
#load all logfiles
|
||||||
|
data = None
|
||||||
|
for logfile in logfiles:
|
||||||
|
try:
|
||||||
|
d = pd.read_csv("app/static/testdata.csv", parse_dates=[0])
|
||||||
|
if data:
|
||||||
|
data = pd.concat((data, d))
|
||||||
|
else:
|
||||||
|
data = d
|
||||||
|
except:
|
||||||
|
logging.error("error while loading file " + logfile)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
#ipdb.set_trace()
|
||||||
|
data = data.set_index(pd.DatetimeIndex(data.time))
|
||||||
|
data = data.drop("time", axis=1)
|
||||||
|
#ipdb.set_trace()
|
||||||
|
plt.xkcd()
|
||||||
|
#all columns
|
||||||
|
for item, frame in data.iteritems():
|
||||||
|
f = plt.figure()
|
||||||
|
#f.patch.set_facecolor("#ccefff")
|
||||||
|
#f.patch.set_alpha("0.0")
|
||||||
|
logging.debug("column " + str(item) + " " + frame.name)
|
||||||
|
plt.plot(data.index.to_pydatetime(), frame, "b")
|
||||||
|
ax = plt.gca()
|
||||||
|
#ax.grid(True, linewidth=1.0)
|
||||||
|
plt.xlim(begin, today)
|
||||||
|
ax.spines['right'].set_visible(False)
|
||||||
|
ax.spines['top'].set_visible(False)
|
||||||
|
ax.yaxis.set_ticks_position('none')#('left')
|
||||||
|
ax.xaxis.set_ticks_position('none')#('bottom')
|
||||||
|
|
||||||
|
f.autofmt_xdate()
|
||||||
|
|
||||||
|
#plt.tick_params(which='minor', length=4)
|
||||||
|
#plt.tick_params(which='major', length=5)
|
||||||
|
#ipdb.set_trace()
|
||||||
|
ax.fmt_xdata = DateFormatter('%d.%m')
|
||||||
|
#ax.xaxis.set_major_locator(WeekdayLocator(MONDAY))
|
||||||
|
#ax.xaxis.set_major_locator(DayLocator())
|
||||||
|
ax.xaxis.set_major_formatter(DateFormatter('%d.%m'))
|
||||||
|
|
||||||
|
|
||||||
|
#plt.xlabel('Datum')
|
||||||
|
#plt.ylabel('Temperatur / C')
|
||||||
|
outfile = "app/static/log_" + str(item) + ".png"
|
||||||
|
logging.info("plot plot_total " + str(datetime.datetime.now()))
|
||||||
|
#480x320
|
||||||
|
plt.gcf().set_size_inches(5.3, 2.4)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig(outfile, dpi=70, transparent=True, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
logging.info("end plot_list " + str(datetime.datetime.now()))
|
||||||
|
|
||||||
|
|
||||||
def plot_list(duration):
|
def plot_list(duration):
|
||||||
print "start plot_list " + str(datetime.datetime.now())
|
logging.info("start plot_list " + str(datetime.datetime.now()))
|
||||||
today = datetime.datetime.today()
|
today = datetime.datetime.today()
|
||||||
begin = today - datetime.timedelta(weeks=duration)
|
begin = today - datetime.timedelta(weeks=duration)
|
||||||
|
|
||||||
@@ -180,11 +247,11 @@ def plot_list(duration):
|
|||||||
|
|
||||||
plt.title("Bierliste ("+ str(duration) + " Wochen)")
|
plt.title("Bierliste ("+ str(duration) + " Wochen)")
|
||||||
|
|
||||||
print "plot plot_list " + str(datetime.datetime.now())
|
logging.info("plot plot_list " + str(datetime.datetime.now()))
|
||||||
#800x600
|
#800x600
|
||||||
fig.set_size_inches(15, 10)
|
fig.set_size_inches(15, 10)
|
||||||
plt.savefig('app/static/bierliste_small.png', dpi=72, bbox_inches='tight')
|
plt.savefig('app/static/bierliste_small.png', dpi=72, bbox_inches='tight')
|
||||||
#1024x768
|
#1024x768
|
||||||
#fig.set_size_inches(10.24, 7.68)
|
#fig.set_size_inches(10.24, 7.68)
|
||||||
#plt.savefig('app/static/bierliste.png', dpi=100)
|
#plt.savefig('app/static/bierliste.png', dpi=100)
|
||||||
print "end plot_list " + str(datetime.datetime.now())
|
logging.info("end plot_list " + str(datetime.datetime.now()))
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
################################################################
|
################################################################
|
||||||
# Settings #
|
# Settings #
|
||||||
################################################################
|
################################################################
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
|
from fridge import Fridge, Sensor
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
|
|
||||||
@@ -40,7 +42,30 @@ class Settings:
|
|||||||
self.annoyDays = 20 #Automatically send mails every x days (default 20)
|
self.annoyDays = 20 #Automatically send mails every x days (default 20)
|
||||||
self.annoyLimit = 100 #Money limit for autoAnnoy (default 100)
|
self.annoyLimit = 100 #Money limit for autoAnnoy (default 100)
|
||||||
|
|
||||||
|
##Data Logging
|
||||||
|
#Fridge Temperature
|
||||||
|
self.fridgeLogging = False #Log the fridge temperature (connect temp. sensors before enabling)
|
||||||
|
self.fridgeTime = 300 #Write fridge temp to file every x seconds
|
||||||
|
self.fridgeLength = 30 #Length of data log span in days
|
||||||
|
|
||||||
##Developer Settings
|
##Developer Settings
|
||||||
self.debug = False #Show debug output in console
|
self.debug = False #Show debug output in console
|
||||||
|
|
||||||
|
##Data Logging - Fridges
|
||||||
|
self.fridges = list() #Do not edit
|
||||||
|
|
||||||
|
#Create an antialcoholic fridge (Antikühlschrank) with 3 sensors (top, middle and bottom temp.)
|
||||||
|
new_f = Fridge("Antikühlschrank") #make new fridge
|
||||||
|
new_f.add_sensor(Sensor("Temperatur Oben", "1")) #add sensor 1 as top
|
||||||
|
new_f.add_sensor(Sensor("Temperatur Mitte", "2")) #add sensor 2 as middle
|
||||||
|
new_f.add_sensor(Sensor("Temperatur Unten", "3")) #add sensor 3 as bottom
|
||||||
|
self.fridges.append(new_f) #append to the list of fridges
|
||||||
|
|
||||||
|
#Create an alcoholic fridge with 3 sensors #add more fridges as you like
|
||||||
|
new_f = Fridge("Bierkühlschrank")
|
||||||
|
new_f.add_sensor(Sensor("Temperatur Oben", "4"))
|
||||||
|
new_f.add_sensor(Sensor("Temperatur Mitte", "5"))
|
||||||
|
new_f.add_sensor(Sensor("Temperatur Unten", "6"))
|
||||||
|
self.fridges.append(new_f)
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
|
|||||||
@@ -122,4 +122,38 @@ input[type=button], input[type=submit], input[type=reset] {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin: 8px 0px;
|
margin: 8px 0px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SECTION: FRIDGE */
|
||||||
|
|
||||||
|
div.fridge { background-color:#FFCC00;
|
||||||
|
margin:20px;
|
||||||
|
padding:10px;
|
||||||
|
padding-left:15px;
|
||||||
|
padding-right:15px;
|
||||||
|
padding-bottom:20px;
|
||||||
|
border-radius:5px;
|
||||||
|
border:4px solid black;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.fridge_top { color:black;
|
||||||
|
padding:2px;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.fridge_bottom { background-color:#AACCFF;
|
||||||
|
padding:2px;
|
||||||
|
border-radius:4px;
|
||||||
|
border:3px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.fridge_sensor { background-color:#E3E6FF; /*#CCEFFF;*/
|
||||||
|
text-align:center;
|
||||||
|
min-height: 170px;
|
||||||
|
padding:3px;
|
||||||
|
border-radius:2px;
|
||||||
|
border:1px;
|
||||||
|
border-color:#CCCCCC;
|
||||||
|
margin: 3px
|
||||||
}
|
}
|
||||||
19
app/views.py
19
app/views.py
@@ -1,9 +1,12 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from check_rights import *
|
from check_rights import *
|
||||||
from flask import render_template, request, redirect, session, send_from_directory
|
from flask import render_template, request, redirect, session, send_from_directory
|
||||||
from app import app
|
from app import app
|
||||||
from database import *
|
from database import *
|
||||||
from plot import *
|
from plot import *
|
||||||
from user import User
|
from user import User
|
||||||
|
from fridge import Fridge, Sensor
|
||||||
from product import Product
|
from product import Product
|
||||||
from send_email import send_email, send_emails
|
from send_email import send_email, send_emails
|
||||||
from consumption import Consumption
|
from consumption import Consumption
|
||||||
@@ -62,6 +65,12 @@ def logout():
|
|||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/fridges')
|
||||||
|
def fridges():
|
||||||
|
plot_log(30, ("static/testdata.csv",))
|
||||||
|
return render_template('fridges.html', fridges=settings.fridges, user=get_user_by_name(session.get('name')))
|
||||||
|
|
||||||
|
|
||||||
@app.route('/manage_users')
|
@app.route('/manage_users')
|
||||||
@requires_baron
|
@requires_baron
|
||||||
def manage_users():
|
def manage_users():
|
||||||
@@ -179,10 +188,8 @@ def manage_beverages_edit(name=None):
|
|||||||
p.isshown = False
|
p.isshown = False
|
||||||
|
|
||||||
pic = request.files['file']
|
pic = request.files['file']
|
||||||
print pic.filename
|
|
||||||
if pic:
|
if pic:
|
||||||
extension = pic.filename.rsplit('.', 1)[1].lower()
|
extension = pic.filename.rsplit('.', 1)[1].lower()
|
||||||
print extension
|
|
||||||
if extension == "png" or extension == "jpg":
|
if extension == "png" or extension == "jpg":
|
||||||
pic.seek(0) # Move cursor back to beginning so we can write to disk
|
pic.seek(0) # Move cursor back to beginning so we can write to disk
|
||||||
fpath = os.path.join("./app/static/", "product_%s.png" % p.name)
|
fpath = os.path.join("./app/static/", "product_%s.png" % p.name)
|
||||||
@@ -201,7 +208,7 @@ def manage_beverages_add():
|
|||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
p = Product()
|
p = Product()
|
||||||
error = None
|
error = None
|
||||||
print request
|
logging.info(request)
|
||||||
p.name = request.form['name']
|
p.name = request.form['name']
|
||||||
#if request.form['price'].isnumeric():
|
#if request.form['price'].isnumeric():
|
||||||
p.price = float(request.form['price'])
|
p.price = float(request.form['price'])
|
||||||
@@ -214,10 +221,10 @@ def manage_beverages_add():
|
|||||||
p.isshown = False
|
p.isshown = False
|
||||||
|
|
||||||
pic = request.files['file']
|
pic = request.files['file']
|
||||||
print pic.filename
|
logging.info(pic.filename)
|
||||||
if pic:
|
if pic:
|
||||||
extension = pic.filename.rsplit('.', 1)[1].lower()
|
extension = pic.filename.rsplit('.', 1)[1].lower()
|
||||||
print extension
|
logging.info(extension)
|
||||||
if extension == "png" or extension == "jpg":
|
if extension == "png" or extension == "jpg":
|
||||||
pic.seek(0) # Move cursor back to beginning so we can write to disk
|
pic.seek(0) # Move cursor back to beginning so we can write to disk
|
||||||
fpath = os.path.join("./app/static/", "product_%s.png" % p.name)
|
fpath = os.path.join("./app/static/", "product_%s.png" % p.name)
|
||||||
@@ -277,7 +284,7 @@ def billing():
|
|||||||
payment = float(request.form[formname])
|
payment = float(request.form[formname])
|
||||||
if payment != 0:
|
if payment != 0:
|
||||||
add_deposit(user.name, payment)
|
add_deposit(user.name, payment)
|
||||||
print "%s payed %d" % (user.name, payment)
|
logging.info("%s payed %d" % (user.name, payment))
|
||||||
debt = [0 for user in users]
|
debt = [0 for user in users]
|
||||||
users = get_users() # refresh users for correct viewing of autounblacking
|
users = get_users() # refresh users for correct viewing of autounblacking
|
||||||
for user in users:
|
for user in users:
|
||||||
|
|||||||
Reference in New Issue
Block a user