Files
POC-Java-www/pocwww/measurements.py
2017-04-19 16:03:35 -05:00

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}