283 lines
11 KiB
Python
283 lines
11 KiB
Python
from pyramid.view import view_config
|
|
from pyramid.httpexceptions import HTTPFound
|
|
from pyramid.security import remember, forget
|
|
from datetime import datetime, timedelta
|
|
from functools import reduce
|
|
import pytz
|
|
from itertools import groupby
|
|
|
|
|
|
def get_date_measurements(request, d, tagname=None):
|
|
find_datetime = datetime(d.year, d.month, d.day, 0, 0, 0)
|
|
if tagname:
|
|
return list(request.db['measurements'].find({"dateStored": find_datetime, 'tagname': tagname}))
|
|
return list(request.db['measurements'].find({"dateStored": find_datetime}))
|
|
|
|
|
|
def expand_measurements_from_document(doc):
|
|
base_date = doc['dateStored']
|
|
value_list = []
|
|
values = doc['values']
|
|
for hour in values:
|
|
for minute in values[hour]:
|
|
measurement_datetime = datetime(base_date.year, base_date.month, base_date.day, int(hour), int(minute), tzinfo=pytz.utc)
|
|
# print("{} = {}".format(measurement_datetime, values[hour][minute]))
|
|
value_list.append({'timestamp': measurement_datetime, 'tagvalue': values[hour][minute]})
|
|
value_list.sort(key=lambda x: x['timestamp'], reverse=True)
|
|
doc['values'] = value_list
|
|
return doc
|
|
|
|
|
|
def get_measurements_between(request, start_datetime, end_datetime, tagname=None):
|
|
start_date = datetime(start_datetime.year, start_datetime.month, start_datetime.day, 0, 0, 0, tzinfo=pytz.utc)
|
|
end_date = datetime(end_datetime.year, end_datetime.month, end_datetime.day, 0, 0, 0, tzinfo=pytz.utc)
|
|
found_measurements = []
|
|
if tagname:
|
|
found_measurements = list(map(expand_measurements_from_document, list(request.db['measurements'].find({"dateStored": {"$lte": end_date, "$gte": start_date}, 'tagname': tagname}))))
|
|
else:
|
|
found_measurements = list(map(expand_measurements_from_document, list(request.db['measurements'].find({"dateStored": {"$lte": end_date, "$gte": start_date}}))))
|
|
|
|
for i in range(0, len(found_measurements)):
|
|
found_measurements[i]['values'] = list(filter(lambda x: x['timestamp'] >= start_datetime and x['timestamp'] <= end_datetime, found_measurements[i]['values']))
|
|
return found_measurements
|
|
|
|
|
|
def combine_measurements(m1, m2):
|
|
new_measurement = {
|
|
"averages": [],
|
|
"totals": [],
|
|
"maxes": [],
|
|
"mins": [],
|
|
"units": m1["units"],
|
|
"values": sorted(m2['values'] + m1['values'], key=lambda x: x['timestamp'], reverse=True),
|
|
"tagname": m1["tagname"],
|
|
}
|
|
|
|
# Average Value
|
|
try:
|
|
new_measurement['averages'] = m1['averages']
|
|
new_measurement['averages'].append({"timestamp": m2['dateStored'], "averageValue": m2['averageValue']})
|
|
except KeyError:
|
|
new_measurement['averages'].append({"timestamp": m1['dateStored'], "averageValue": m1['averageValue']})
|
|
new_measurement['averages'].append({"timestamp": m2['dateStored'], "averageValue": m2['averageValue']})
|
|
|
|
# Total Value
|
|
try:
|
|
new_measurement['totals'] = m1['totals']
|
|
new_measurement['totals'].append({"timestamp": m2['dateStored'], "totalValue": m2['totalValue']})
|
|
except KeyError:
|
|
new_measurement['totals'].append({"timestamp": m1['dateStored'], "totalValue": m1['totalValue']})
|
|
new_measurement['totals'].append({"timestamp": m2['dateStored'], "totalValue": m2['totalValue']})
|
|
|
|
# Max Value
|
|
try:
|
|
new_measurement['maxes'] = m1['maxes']
|
|
new_measurement['maxes'].append({"timestamp": m2['dateStored'], "maxValue": m2['maxValue']})
|
|
except KeyError:
|
|
new_measurement['maxes'].append({"timestamp": m1['dateStored'], "maxValue": m1['maxValue']})
|
|
new_measurement['maxes'].append({"timestamp": m2['dateStored'], "maxValue": m2['maxValue']})
|
|
|
|
# Min Value
|
|
try:
|
|
new_measurement['mins'] = m1['mins']
|
|
new_measurement['mins'].append({"timestamp": m2['dateStored'], "minValue": m2['minValue']})
|
|
except KeyError:
|
|
new_measurement['mins'].append({"timestamp": m1['dateStored'], "minValue": m1['minValue']})
|
|
new_measurement['mins'].append({"timestamp": m2['dateStored'], "minValue": m2['minValue']})
|
|
|
|
return new_measurement
|
|
|
|
|
|
def first_measurement(m1):
|
|
new_measurement = {
|
|
"averages": [],
|
|
"totals": [],
|
|
"maxes": [],
|
|
"mins": [],
|
|
"units": m1["units"],
|
|
"values": sorted(m1['values'], key=lambda x: x['timestamp'], reverse=True),
|
|
"tagname": m1["tagname"],
|
|
}
|
|
|
|
# Average Value
|
|
try:
|
|
new_measurement['averages'] = m1['averages']
|
|
except KeyError:
|
|
new_measurement['averages'].append({"timestamp": m1['dateStored'], "averageValue": m1['averageValue']})
|
|
|
|
# Total Value
|
|
try:
|
|
new_measurement['totals'] = m1['totals']
|
|
except KeyError:
|
|
new_measurement['totals'].append({"timestamp": m1['dateStored'], "totalValue": m1['totalValue']})
|
|
|
|
# Max Value
|
|
try:
|
|
new_measurement['maxes'] = m1['maxes']
|
|
except KeyError:
|
|
new_measurement['maxes'].append({"timestamp": m1['dateStored'], "maxValue": m1['maxValue']})
|
|
|
|
# Min Value
|
|
try:
|
|
new_measurement['mins'] = m1['mins']
|
|
except KeyError:
|
|
new_measurement['mins'].append({"timestamp": m1['dateStored'], "minValue": m1['minValue']})
|
|
|
|
return new_measurement
|
|
|
|
|
|
def get_grouped_measurements_between(request, start_datetime, end_datetime, tagname=None):
|
|
data = sorted(get_measurements_between(request, start_datetime, end_datetime, tagname=tagname), key=lambda x: x['tagname'])
|
|
tag_data = {}
|
|
for k, g in groupby(data, lambda x: x['tagname']):
|
|
group = list(g)
|
|
if len(group) > 1:
|
|
tag_data[k] = reduce(combine_measurements, group)
|
|
else:
|
|
tag_data[k] = first_measurement(group[0])
|
|
|
|
return tag_data
|
|
|
|
|
|
@view_config(route_name='measurements_all', renderer="templates/valuesall.jinja2")
|
|
def values_page(request):
|
|
latest_tag_values = []
|
|
latesttag_agg = request.db['measurements'].aggregate([
|
|
{'$sort': {'dateStored': 1}},
|
|
{
|
|
'$group': {
|
|
'_id': '$tagname',
|
|
'currentValue': {'$last': '$currentValue'},
|
|
'units': {'$last': '$units'},
|
|
'maxValue': {'$last': '$maxValue'},
|
|
'minValue': {'$last': '$minValue'},
|
|
'totalValue': {'$last': '$totalValue'},
|
|
'averageValue': {'$last': '$averageValue'},
|
|
'useTotal': {'$last': '$useTotal'},
|
|
'useAverage': {'$last': '$useAverage'}
|
|
}
|
|
}
|
|
])
|
|
for t in latesttag_agg:
|
|
latest_tag_values.append(t)
|
|
|
|
return {'navgroup': 'values', "current_values": latest_tag_values}
|
|
|
|
|
|
@view_config(route_name='measurements_all_json', renderer='prettyjson')
|
|
def values_all(request):
|
|
end = datetime.now(tz=pytz.utc)
|
|
try: # Attempt to get a value from the request.
|
|
end = request.matchdict['enddt']
|
|
end = end.replace("T", " ")
|
|
end = pytz.utc.localize(datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ"))
|
|
except KeyError:
|
|
pass
|
|
|
|
start = end - timedelta(days=2)
|
|
try: # Attempt to get a value from the request.
|
|
start = request.matchdict['startdt']
|
|
start = start.replace("T", " ")
|
|
start = pytz.utc.localize(datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ"))
|
|
except KeyError:
|
|
pass
|
|
|
|
latest_tag_values = []
|
|
latesttag_agg = request.db['measurements'].aggregate([
|
|
{'$sort': {'dateStored': 1}},
|
|
{
|
|
'$group': {
|
|
'_id': '$tagname',
|
|
'currentValue': {'$last': '$currentValue'},
|
|
'units': {'$last': '$units'},
|
|
'maxValue': {'$last': '$maxValue'},
|
|
'minValue': {'$last': '$minValue'},
|
|
'totalValue': {'$last': '$totalValue'},
|
|
'averageValue': {'$last': '$averageValue'},
|
|
'useTotal': {'$last': '$useTotal'},
|
|
'useAverage': {'$last': '$useAverage'}
|
|
}
|
|
}
|
|
])
|
|
for t in latesttag_agg:
|
|
latest_tag_values.append(t)
|
|
|
|
all_values = get_grouped_measurements_between(request, start, end)
|
|
return {'navgroup': 'values', 'values': all_values, "current_values": latest_tag_values}
|
|
|
|
|
|
@view_config(route_name="measurements_singlebetween_json", renderer="prettyjson")
|
|
@view_config(route_name="measurements_singlebetween_wparams_json", renderer="prettyjson")
|
|
def json_singlevaluebetween(request):
|
|
end = datetime.now(tz=pytz.utc)
|
|
try: # Attempt to get a value from the request.
|
|
end = request.matchdict['enddt']
|
|
end = end.replace("T", " ")
|
|
end = pytz.utc.localize(datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ"))
|
|
except KeyError:
|
|
pass
|
|
|
|
start = end - timedelta(days=7)
|
|
try: # Attempt to get a value from the request.
|
|
start = request.matchdict['startdt']
|
|
start = start.replace("T", " ")
|
|
start = pytz.utc.localize(datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ"))
|
|
except KeyError:
|
|
pass
|
|
|
|
all_values = get_grouped_measurements_between(request, start, end, tagname=request.matchdict['tagname'])
|
|
return {'tag': all_values, 'start': start, 'end': end, 'tagname': request.matchdict['tagname']}
|
|
|
|
|
|
@view_config(route_name="measurements_between_json", renderer="prettyjson")
|
|
@view_config(route_name="measurements_between_wparams_json", renderer="prettyjson")
|
|
def json_valuesbetween(request):
|
|
end = datetime.now(tz=pytz.utc)
|
|
try: # Attempt to get a value from the request.
|
|
end = request.matchdict['enddt']
|
|
end = end.replace("T", " ")
|
|
end = pytz.utc.localize(datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ"))
|
|
except KeyError:
|
|
pass
|
|
|
|
start = end - timedelta(days=2)
|
|
try: # Attempt to get a value from the request.
|
|
start = request.matchdict['startdt']
|
|
start = start.replace("T", " ")
|
|
start = pytz.utc.localize(datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ"))
|
|
except KeyError:
|
|
pass
|
|
|
|
tag_data = get_grouped_measurements_between(request, start, end)
|
|
return {'values': tag_data, 'start': start, 'end': end}
|
|
|
|
|
|
@view_config(route_name="measurements_daterange_json", renderer="prettyjson")
|
|
def json_valuesdaterange(request):
|
|
date_limits = list(request.db['measurements'].aggregate([
|
|
{"$group": {
|
|
"_id": 'null',
|
|
"last": {"$max": "$dateStored"},
|
|
"first": {"$min": "$dateStored"}
|
|
}}
|
|
]))[0]
|
|
return {'first_date': date_limits['first'], 'last_date': date_limits['last']}
|
|
|
|
|
|
@view_config(route_name="measurements_singledaterange_json", renderer="prettyjson")
|
|
def json_singlevaluedaterange(request):
|
|
date_limits = list(request.db['measurements'].aggregate([
|
|
{"$match": {"tagname": request.matchdict['tagname']}},
|
|
{"$group": {
|
|
"_id": 'null',
|
|
"last": {"$max": "$dateStored"},
|
|
"first": {"$min": "$dateStored"}
|
|
}}
|
|
]))[0]
|
|
return {'first_date': date_limits['first'], 'last_date': date_limits['last']}
|
|
|
|
@view_config(route_name="measurements_single", renderer="templates/values_single.jinja2")
|
|
def measurements_single(request):
|
|
tagname = request.matchdict['tagname']
|
|
return {'navgroup': 'values', 'tagname': tagname}
|