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?
|
||||
#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()))
|
||||
@@ -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()
|
||||
|
||||
@@ -123,3 +123,37 @@ input[type=button], input[type=submit], input[type=reset] {
|
||||
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
|
||||
}
|
||||
19
app/views.py
19
app/views.py
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user