diff --git a/development.ini b/development.ini index f1e5520..8c67182 100644 --- a/development.ini +++ b/development.ini @@ -18,7 +18,7 @@ pyramid.includes = # '127.0.0.1' and '::1'. # debugtoolbar.hosts = 127.0.0.1 ::1 -mongo_uri = mongodb://localhost:27017/poc +mongo_uri = mongodb://poc_www:HenryPump1903@localhost:27017/poc # mongo_uri = mongodb://10.20.155.202:27017/poc diff --git a/pocwww/__init__.py b/pocwww/__init__.py index d696977..b3cfdb9 100644 --- a/pocwww/__init__.py +++ b/pocwww/__init__.py @@ -96,13 +96,12 @@ def main(global_config, **settings): jinja2_env.filters['datestring'] = format_dateString db_url = urlparse(settings['mongo_uri']) + config.registry.db = MongoClient( host=db_url.hostname, port=db_url.port, ) - config.registry.db.poc.users.update_one({"username": "admin"}, {"$set": {"username": "admin", "password": "l3tm31n"}}, upsert=True) - def add_db(request): db = config.registry.db[db_url.path[1:]] if db_url.username and db_url.password: @@ -112,6 +111,10 @@ def main(global_config, **settings): config.add_request_method(add_db, 'db', reify=True) config.add_static_view('static', 'static', cache_max_age=3600) + # Add login for admin user + config.registry.db.poc.authenticate(db_url.username, db_url.password) + config.registry.db.poc.users.update_one({"username": "admin"}, {"$set": {"username": "admin", "password": "l3tm31n"}}, upsert=True) + # CUSTOM JSON RENDERER prettyjson = JSON(indent=4) prettyjson.add_adapter(datetime, datetime_adapter) diff --git a/pocwww/json.py b/pocwww/json.py index d4b7f42..2819e01 100644 --- a/pocwww/json.py +++ b/pocwww/json.py @@ -2,6 +2,7 @@ from pyramid.view import view_config from .view_helpers import * from bson import json_util import requests +import pytz # JSON @@ -63,35 +64,6 @@ def json_valuesdaterange(request): return {'first_date': date_limits['first'], 'last_date': date_limits['last']} -@view_config(route_name="json_singlevaluebetween", renderer="prettyjson") -@view_config(route_name="json_singlevaluebetween_wparams", renderer="prettyjson") -def json_singlevaluebetween(request): - end = datetime.now() - try: # Attempt to get a value from the request. - end = request.matchdict['enddt'] - end = end.replace("T", " ") - end = 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 = datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ") - except KeyError: - pass - - tag_data = [] - grouped_tags = request.db['wellData'].aggregate([ - {"$match": {"tagname": request.matchdict['tagname'], 'timestamp': {'$gt': start, '$lte': end}}}, - { - '$sort': {"timestamp": 1} - } - ]) - return {'values': list(grouped_tags), 'start': start, 'end': end} - - @view_config(route_name="json_singlevaluedaterange", renderer="prettyjson") def json_singlevaluedaterange(request): date_limits = list(request.db['wellData'].aggregate([ diff --git a/pocwww/measurements.py b/pocwww/measurements.py new file mode 100644 index 0000000..f283bb8 --- /dev/null +++ b/pocwww/measurements.py @@ -0,0 +1,185 @@ +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='values_all', renderer="templates/valuesall.jinja2") +@view_config(route_name='json_values_all', 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 + + all_values = get_grouped_measurements_between(request, start, end) + return {'navgroup': 'values', 'current_tag_values': all_values} + + +@view_config(route_name="json_singlevaluebetween", renderer="prettyjson") +@view_config(route_name="json_singlevaluebetween_wparams", 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']} diff --git a/pocwww/static/graphs.js b/pocwww/static/graphs.js index 9c3f9e7..b1aff55 100644 --- a/pocwww/static/graphs.js +++ b/pocwww/static/graphs.js @@ -130,33 +130,95 @@ function drawSingleGraph(data){ console.log("Destroying existing chart"); scatterChart.destroy(); } + + var tag = data.tag[data.tagname]; + console.log(tag); + console.log(tag.values.length); + var graph_data = []; - var values = data.values; var ctx = document.getElementById("myChart"); - var lines = ["currentValue", "maxDailyValue", "minDailyValue", "dailyAverage", "dailyTotal"]; - for (var i = 0; i < lines.length; i++){ - var baseObj = { - label: lines[i], - fill: false, - data: [], - lineTension: 0.05, - borderColor: color_scale[i % color_scale.length] - } - if (lines[i] == "dailyTotal"){ - baseObj['hidden'] = true; - } - graph_data.push(baseObj); + var color_index = 0; + + // Current Values + var currentValues = { + label: "Value", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] } - for(var i = 0; i < values.length; i++){ - for(var j = 0; j < lines.length; j++){ - var lineName = lines[j] - graph_data[lines.indexOf(lineName)].data.push({ - x: values[i].timestamp, - y: values[i][lineName] - }); - } + for (var i = 0; i < tag.values.length; i++){ + currentValues.data.push({x: tag.values.timestamp, y: tag.values.tagvalue}); } + + graph_data.push(currentValues) + color_index++; + + // Max Values + var maxValues = { + label: "Max", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.maxes.length; i++){ + maxValues.data.push({x: tag.maxes.timestamp, y: tag.maxes.maxValue}); + } + + graph_data.push(maxValues) + color_index++; + + // Min Values + var minValues = { + label: "Min", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.mins.length; i++){ + minValues.data.push({x: tag.mins.timestamp, y: tag.mins.maxValue}); + } + + graph_data.push(minValues) + color_index++; + + // Average Values + var averageValues = { + label: "Average", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.averages.length; i++){ + averageValues.data.push({x: tag.averages.timestamp, y: tag.averages.maxValue}); + } + + graph_data.push(averageValues) + color_index++; + + // Total Values + var totalValues = { + label: "Total", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.totals.length; i++){ + totalValues.data.push({x: tag.totals.timestamp, y: tag.totals.maxValue}); + } + + graph_data.push(totalValues) + color_index++; + scatterChart = new Chart(ctx, { type: 'line', data: { diff --git a/pocwww/templates/dashboard.jinja2 b/pocwww/templates/dashboard.jinja2 index e5415d8..f98732e 100644 --- a/pocwww/templates/dashboard.jinja2 +++ b/pocwww/templates/dashboard.jinja2 @@ -23,11 +23,6 @@