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?
#matplotlib.use('GTKAgg')
from matplotlib import pyplot as plt
from matplotlib import units
from matplotlib.dates import WeekdayLocator, DayLocator, HourLocator, DateFormatter, drange, MONDAY
import numpy as np
from user import User
from database import *
import multiprocessing as mp
import pandas as pd
import ipdb
import logging
def plot_all_thread(user=None):
if user is not None:
@@ -21,21 +25,17 @@ def plot_all(user=None):
plot_total(user)
plot_total()
plot_list(4)
print 'plot_all'
logging.info('plot_all')
def plot_total(user=None):
print "start plot_total " + str(datetime.datetime.now())
print 'plot_total'
logging.info("start plot_total")
today = datetime.date.today()
delta = datetime.timedelta(days=1)
begin = today - datetime.timedelta(weeks=2)
dates = drange(begin, today + delta, delta)
#print begin
#print today
#print dates
products = get_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
fill = "app/static/total%03d_big.png" % user.id
plt.title(tit)
print "plot plot_total " + str(datetime.datetime.now())
logging.info("plot plot_total " + str(datetime.datetime.now()))
#480x320
fig.set_size_inches(4.8, 3.2)
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)
#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):
print "start plot_list " + str(datetime.datetime.now())
logging.info("start plot_list " + str(datetime.datetime.now()))
today = datetime.datetime.today()
begin = today - datetime.timedelta(weeks=duration)
@@ -180,11 +247,11 @@ def plot_list(duration):
plt.title("Bierliste ("+ str(duration) + " Wochen)")
print "plot plot_list " + str(datetime.datetime.now())
logging.info("plot plot_list " + str(datetime.datetime.now()))
#800x600
fig.set_size_inches(15, 10)
plt.savefig('app/static/bierliste_small.png', dpi=72, bbox_inches='tight')
#1024x768
#fig.set_size_inches(10.24, 7.68)
#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 #
################################################################
@@ -15,6 +16,7 @@
#
################################################################
from fridge import Fridge, Sensor
class Settings:
@@ -40,7 +42,30 @@ class Settings:
self.annoyDays = 20 #Automatically send mails every x days (default 20)
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
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()

View File

@@ -122,4 +122,38 @@ input[type=button], input[type=submit], input[type=reset] {
text-decoration: none;
margin: 8px 0px;
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 flask import render_template, request, redirect, session, send_from_directory
from app import app
from database import *
from plot import *
from user import User
from fridge import Fridge, Sensor
from product import Product
from send_email import send_email, send_emails
from consumption import Consumption
@@ -62,6 +65,12 @@ def logout():
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')
@requires_baron
def manage_users():
@@ -179,10 +188,8 @@ def manage_beverages_edit(name=None):
p.isshown = False
pic = request.files['file']
print pic.filename
if pic:
extension = pic.filename.rsplit('.', 1)[1].lower()
print extension
if extension == "png" or extension == "jpg":
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)
@@ -201,7 +208,7 @@ def manage_beverages_add():
if request.method == 'POST':
p = Product()
error = None
print request
logging.info(request)
p.name = request.form['name']
#if request.form['price'].isnumeric():
p.price = float(request.form['price'])
@@ -214,10 +221,10 @@ def manage_beverages_add():
p.isshown = False
pic = request.files['file']
print pic.filename
logging.info(pic.filename)
if pic:
extension = pic.filename.rsplit('.', 1)[1].lower()
print extension
logging.info(extension)
if extension == "png" or extension == "jpg":
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)
@@ -277,7 +284,7 @@ def billing():
payment = float(request.form[formname])
if payment != 0:
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]
users = get_users() # refresh users for correct viewing of autounblacking
for user in users: