add: fridges view, fridge+sensor class, plot function, generator for test data

This commit is contained in:
Bernhard Stampfer
2016-05-07 20:48:31 +02:00
parent fba306db5a
commit d124755c88
6 changed files with 193 additions and 19 deletions

15
app/fridge.py Normal file
View 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

View 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

View File

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

View File

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

View File

@@ -123,3 +123,37 @@ input[type=button], input[type=submit], input[type=reset] {
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
}

View File

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