1 Commits

Author SHA1 Message Date
Patrick McDonagh
950d2c1e51 Revert "Optimize time series data" 2017-05-02 10:16:40 -05:00
24 changed files with 674 additions and 909 deletions

2
.gitignore vendored
View File

@@ -1,2 +0,0 @@
env/*
pocwww.egg*

View File

@@ -18,7 +18,7 @@ pyramid.includes =
# '127.0.0.1' and '::1'.
# debugtoolbar.hosts = 127.0.0.1 ::1
mongo_uri = mongodb://poc_www:HenryPump1903@localhost:27017/poc
mongo_uri = mongodb://localhost:27017/poc
# mongo_uri = mongodb://10.20.155.202:27017/poc

View File

@@ -96,12 +96,13 @@ 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:
@@ -111,10 +112,6 @@ 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)
@@ -125,72 +122,73 @@ def main(global_config, **settings):
# SHARED ROUTES
config.add_route('home', '/')
config.add_route('home_json', '/json')
config.add_route('json_snapshot', '/json')
# Cards
config.add_route('cards_page', '/cards/{cards_date}/{page_num}')
config.add_route('cards_page_json', '/json/cards/{cards_date}/{page_num}')
config.add_route('json_cards_page', '/json/cards/{cards_date}/{page_num}')
config.add_route('cards_date', '/cards/{cards_date}')
config.add_route('cards_date_json', '/json/cards/{cards_date}')
config.add_route('json_cards_date', '/json/cards/{cards_date}')
config.add_route('cards', '/cards')
config.add_route('cards_json', '/json/cards')
config.add_route('cards_singlecard', "/card/view/{stroke_number}")
config.add_route('cards_singlecard_json', "/json/card/view/{stroke_number}")
config.add_route('cards_lastcard_json', "/json/lastcard")
config.add_route('json_cards', '/json/cards')
# Measurements
config.add_route('measurements_all', "/values")
config.add_route('measurements_all_json', "/json/values")
config.add_route('measurements_between_wparams_json', "/json/values/between/{startdt}/{enddt}")
config.add_route('measurements_between_json', "/json/values/between")
config.add_route("measurements_daterange_json", "/json/values/daterange")
config.add_route('measurements_singlebetween_wparams_json', "/json/values/tag/{tagname}/between/{startdt}/{enddt}")
config.add_route('measurements_singlebetween_json', "/json/values/tag/{tagname}")
config.add_route("measurements_singledaterange_json", "/json/values/tag/{tagname}/daterange")
config.add_route('measurements_single', "/values/tag/{tagname}")
config.add_route('card_single', "/card/view/{stroke_number}")
config.add_route('json_card_single', "/json/card/view/{stroke_number}")
config.add_route('values_all', "/values")
config.add_route('json_values_all', "/json/values")
config.add_route('values_tag', "/values/tag/{tagname}")
config.add_route('values_time', '/values/time/{time}')
config.add_route('json_values_time', '/json/values/time/{time}')
# Gauge Off
config.add_route('gaugeoff_all', '/gaugeoff')
config.add_route('gaugeoff_all_json', '/json/gaugeoff')
config.add_route('json_gaugeoff_all', '/json/gaugeoff')
# Fluid Shots
config.add_route('fluidshots_all', '/fluidshots')
config.add_route('fluidshots_all_json', '/json/fluidshots')
config.add_route('json_fluidshots_all', '/json/fluidshots')
# Well Tests
config.add_route('welltests_all', '/welltests')
config.add_route('welltests_all_json', '/json/welltests')
config.add_route('json_welltests_all', '/json/welltests')
# Run Status
config.add_route('runstatus', '/runstatus')
config.add_route('runstatus_page_json', '/json/runstatus/{page_num}')
config.add_route('runstatus_json', '/json/runstatus')
config.add_route('runstatus_now_json', "/json/runstatusnow")
config.add_route('json_runstatus_page', '/json/runstatus/{page_num}')
config.add_route('json_runstatus', '/json/runstatus')
# Configuration
config.add_route('config_json', '/json/config', factory='pocwww.security.UserLoginFactory')
config.add_route('json_config', '/json/config', factory='pocwww.security.UserLoginFactory')
config.add_route('config', '/config', factory='pocwww.security.UserLoginFactory')
# Administration
config.add_route('json_setpoints', '/json/setpoints', factory='pocwww.security.UserLoginFactory')
config.add_route('json_mode', '/json/mode', factory='pocwww.security.UserLoginFactory')
config.add_route('setpoints', '/setpoints', factory='pocwww.security.UserLoginFactory')
config.add_route('admin', '/admin', factory='pocwww.security.UserLoginFactory')
config.add_route('auth', '/sign/{action}')
config.add_route('register', '/register', factory='pocwww.security.UserLoginFactory')
# Users
config.add_route('users_auth', '/sign/{action}')
config.add_route('users_register', '/register', factory='pocwww.security.UserLoginFactory')
config.add_route("users_json", "/json/users", factory='pocwww.security.UserLoginFactory')
# JSON-ONLY ROUTES
config.add_route('json_lastcard', "/json/lastcard")
config.add_route('json_runstatusnow', "/json/runstatusnow")
config.add_route('json_valuesbetween_wparams', "/json/values/between/{startdt}/{enddt}")
config.add_route('json_valuesbetween', "/json/values/between")
config.add_route("json_valuesdaterange", "/json/values/daterange")
# POC Interface
config.add_route("poc_updateconfig_json", "/json/updateconfig", factory='pocwww.security.UserLoginFactory')
config.add_route("poc_shake_json", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') # Shake command is separate for allowing all access
config.add_route("poc_cmd_json", '/json/cmd/{action}', factory='pocwww.security.UserLoginFactory')
config.add_route("poc_updatepocaddress_json", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory')
config.add_route('poc_setpoints_json', '/json/setpoints', factory='pocwww.security.UserLoginFactory')
config.add_route('poc_mode_json', '/json/mode', factory='pocwww.security.UserLoginFactory')
config.add_route('poc_setpoints', '/setpoints', factory='pocwww.security.UserLoginFactory')
config.add_route('json_singlevaluebetween_wparams', "/json/values/tag/{tagname}/between/{startdt}/{enddt}")
config.add_route('json_singlevaluebetween', "/json/values/tag/{tagname}")
config.add_route("json_singlevaluedaterange", "/json/values/tag/{tagname}/daterange")
config.add_route("json_updateconfig", "/json/updateconfig", factory='pocwww.security.UserLoginFactory')
config.add_route("json_shake", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory')
config.add_route("json_cmd", '/json/cmd/{action}', factory='pocwww.security.UserLoginFactory')
# config.add_route("json_cmd_start", "/json/cmd/start", factory='pocwww.security.UserLoginFactory')
# config.add_route("json_cmd_stop", "/json/cmd/stop", factory='pocwww.security.UserLoginFactory')
# config.add_route("json_cmd_shake", "/json/cmd/shake", factory='pocwww.security.UserLoginFactory')
config.add_route("json_update_poc_address", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory')
config.add_route("json_users", "/json/users", factory='pocwww.security.UserLoginFactory')
config.scan()
return config.make_wsgi_app()

View File

@@ -1,7 +0,0 @@
from pyramid.view import view_config
@view_config(route_name="admin", renderer="templates/admin.jinja2", permission="edit")
def admin_view(request):
address = get_poc_address(request) or 'localhost'
return {'navgroup': 'admin', 'pocIPAddress': address}

View File

@@ -1,87 +0,0 @@
from pyramid.view import view_config
from datetime import datetime
from datetime import timedelta
from math import ceil
from .pagination import Pagination
def get_all_dates_with_cards(request):
datelist = []
dateagg = request.db['cards'].aggregate([
{"$group": {
"_id": {"$concat": [
{"$substr": [{"$year": "$timestamp"}, 0, 4]},
"-",
{"$substr": [{"$month": "$timestamp"}, 0, 2]},
"-",
{"$substr": [{"$dayOfMonth": "$timestamp"}, 0, 2]},
]},
"count": {"$sum": 1}
}},
{"$sort": {"_id": -1}}
])
for d in dateagg:
datelist.append({'count': d['count'], 'date': datetime.strptime(d['_id'], "%Y-%m-%d").date()})
return list(datelist)
@view_config(route_name="cards_lastcard_json", renderer="prettyjson")
def json_lastcard(request):
return get_latest_card(request)
@view_config(route_name='cards', renderer='templates/datelist.jinja2')
@view_config(route_name='cards_json', renderer='prettyjson')
def cards(request):
return {'datelist': get_all_dates_with_cards(request), 'navgroup': 'cards'}
@view_config(route_name='cards_page', renderer='templates/cardlist.jinja2')
@view_config(route_name='cards_date', renderer='templates/cardlist.jinja2')
@view_config(route_name='cards_date_json', renderer='prettyjson')
@view_config(route_name='cards_page_json', renderer='prettyjson')
def cards_page(request):
page_num = 1
try:
page_num = int(request.matchdict['page_num'])
except KeyError:
pass
cards_date_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
try:
cards_date_start = datetime.strptime(request.matchdict['cards_date'], "%Y-%m-%d")
except KeyError:
pass
cards_date_end = cards_date_start + timedelta(days=1)
num_per_page = 100
num_cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).count()
pages = ceil(num_cards / num_per_page)
cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page)
return {
'cards': list(cards),
'pagination': Pagination(page_num, num_per_page, num_cards),
'cards_date': cards_date_start.strftime("%Y-%m-%d"), 'navgroup': 'cards',
'datelist': get_all_dates_with_cards(request)
}
@view_config(route_name='cards_singlecard', renderer='templates/cardsingle.jinja2')
@view_config(route_name='cards_singlecard_json', renderer='prettyjson')
def card_single(request):
card = {}
try:
card = list(request.db['cards'].find({"strokeNumber": int(request.matchdict['stroke_number'])}))[0]
except IndexError:
pass
datepage_url = request.referrer.split("/")[3:]
page_num = 1
carddate = ""
if len(datepage_url) > 2:
page_num = int(datepage_url[2])
if len(datepage_url) > 1:
carddate = datepage_url[1]
return {"card": card, 'navgroup': 'cards', 'datelist': get_all_dates_with_cards(request), 'date': carddate, 'datepage': page_num}

View File

@@ -1,7 +0,0 @@
from pyramid.view import view_config
@view_config(route_name="config", renderer="templates/config.jinja2", permission="edit")
@view_config(route_name="config_json", renderer="prettyjson", permission="edit")
def well_config(request):
current_configuration = list(request.db['wellConfiguration'].find().sort("timestamp", -1).limit(1))[0]
return {'navgroup': 'config', 'config': current_configuration}

View File

@@ -1,8 +0,0 @@
from pyramid.view import view_config
@view_config(route_name="fluidshots_all", renderer="templates/fluidshots.jinja2")
@view_config(route_name="fluidshots_all_json", renderer="prettyjson")
def fluidshots_all(request):
fluidshots = list(request.db['fluidShots'].find())
return {'navgroup': 'fluidshots', 'data': fluidshots}

View File

@@ -1,44 +0,0 @@
from pyramid.view import view_config
@view_config(route_name="gaugeoff_all", renderer="templates/gaugeoff_all.jinja2")
@view_config(route_name="gaugeoff_all_json", renderer="prettyjson")
def gaugeoff_all(request):
gaugeoff_list = []
dateagg = list(request.db['gaugeOff'].aggregate(
[
{
'$project': {
'yearMonthDay': {'$dateToString': {'format': "%Y-%m-%d", 'date': "$timestamp"}},
'tagname': 1,
'dailyTotal': 1,
'dailyAverage': 1,
'maxDailyValue': 1,
'minDailyValue': 1,
'currentValue': 1
}
},
{
'$group': {
'_id': "$yearMonthDay",
'tags': {'$push': {'name': "$tagname"}},
'totals': {'$push': {'total': "$dailyTotal"}},
'averages': {'$push': {'average': "$dailyAverage"}},
'max': {'$push': {'max': "$maxDailyValue"}},
'min': {'$push': {'min': "$minDailyValue"}},
'last': {'$push': {'last': "$currentValue"}}
}
}
]))
for d in dateagg:
newGO = {'date': datetime.strptime(d["_id"], '%Y-%m-%d'), 'tags': {}}
for i in range(0, len(d['tags'])):
newTagObj = {
"max": d['max'][i]['max'],
"min": d['min'][i]['min'],
"last": d['last'][i]['last'],
"total": d['totals'][i]['total'],
"average": d['averages'][i]['average'],
}
newGO['tags'][d['tags'][i]['name']] = newTagObj
gaugeoff_list.append(newGO)
return {'navgroup': 'gaugeoff', 'data': gaugeoff_list}

View File

@@ -1,33 +0,0 @@
from pyramid.view import view_config
@view_config(route_name='home', renderer='templates/dashboard.jinja2')
@view_config(route_name="home_json", renderer="prettyjson")
def my_view(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)
latest_card = []
try:
latest_card = list(request.db['cards'].find().sort("timestamp", -1).limit(1))[0]
except IndexError:
latest_card = []
return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': latest_tag_values, 'card': latest_card}

293
pocwww/json.py Normal file
View File

@@ -0,0 +1,293 @@
from pyramid.view import view_config
from .view_helpers import *
from bson import json_util
import requests
# JSON
@view_config(route_name="json_lastcard", renderer="prettyjson")
def json_lastcard(request):
return get_latest_card(request)
@view_config(route_name="json_valuesbetween", renderer="prettyjson")
@view_config(route_name="json_valuesbetween_wparams", renderer="prettyjson")
def json_valuesbetween(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=2)
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': {"timestamp": {"$gt": start, "$lte": end}}
},
{
'$sort': {"tagname": 1, "timestamp": 1}
},
{
'$group': {
'_id': "$tagname",
'timestamps': {'$push': "$timestamp"},
'currentValues': {'$push': "$currentValue"}
}
}
])
for t in grouped_tags:
tag_data.append({"tagname": t['_id'], "timestamps": list(map(lambda a: a.strftime("%Y-%m-%d %H:%M:%S.%fZ"), t['timestamps'])), "currentValues": t['currentValues']})
return {'values': tag_data, 'start': start, 'end': end}
@view_config(route_name="json_valuesdaterange", renderer="prettyjson")
def json_valuesdaterange(request):
date_limits = list(request.db['wellData'].aggregate([
{"$group": {
"_id": 'null',
"last": {"$max": "$timestamp"},
"first": {"$min": "$timestamp"}
}}
]))[0]
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([
{"$match": {"tagname": request.matchdict['tagname']}},
{"$group": {
"_id": 'null',
"last": {"$max": "$timestamp"},
"first": {"$min": "$timestamp"}
}}
]))[0]
return {'first_date': date_limits['first'], 'last_date': date_limits['last']}
@view_config(route_name="json_runstatusnow", renderer="prettyjson")
def json_runstatusnow(request):
status = False
try:
status = list(request.db['runStatus'].find().sort("timestamp", -1).limit(1))[0]
except IndexError:
pass
return {'runstatus': status}
@view_config(route_name="json_updateconfig", renderer="prettyjson", request_method='POST', permission="edit")
def json_updateconfig(request):
conv_to_float = [
'deltaT',
'pumpDiameter',
'fluidGradient',
'tubingID',
'tubingOD',
'tubingAnchorDepth',
'structuralRating',
'stuffingBoxFriction',
'tubingHeadPressure'
]
t_conv_to_float = ['length', 'diameter', 'dampingFactor']
jsb = request.json_body
new_config = {}
new_config['timestamp'] = datetime.utcnow()
new_config['storedBy'] = request.authenticated_userid
new_config['wellName'] = jsb['wellName']
new_config['tapers'] = []
for p in conv_to_float:
new_config[p] = float(jsb[p])
for t_i in range(0, len(jsb['tapers'])):
t = {}
for p in t_conv_to_float:
t[p] = float(jsb['tapers'][t_i][p])
t['material'] = jsb['tapers'][t_i]['material']
new_config['tapers'].append(t)
result = request.db['wellConfiguration'].insert(new_config)
addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"}))
address = 'localhost'
if len(addr_obj) > 0:
address = addr_obj[0]['pocIPAddress']
update_url = "http://{}:8000/config?update=true".format(address)
r = requests.get(update_url)
pocCmdSts = "OK" if r.status_code == 200 else "failed"
return {'new_config': request.json_body, 'stored_result': result, 'updated': pocCmdSts}
@view_config(route_name="json_cmd", renderer="prettyjson", permission="edit")
def json_cmd(request):
action = request.matchdict['action']
address = get_poc_address(request) or 'localhost'
java_url = {}
java_url['start'] = "http://{}:8000/command?cmd=start&user={}".format(address, request.authenticated_userid)
java_url['stop'] = "http://{}:8000/command?cmd=stop&user={}".format(address, request.authenticated_userid)
java_url['shake'] = "http://{}:8000/shake".format(address)
r = requests.get(java_url[action])
return r.text if r.status_code == 200 else {"status": "failure sending command"}
@view_config(route_name="json_shake", renderer="prettyjson", permission="view")
def json_shake(request):
address = get_poc_address(request) or 'localhost'
url = "http://{}:8000/shake".format(address)
r = requests.get(url)
return r.text if r.status_code == 200 else {"status": "failure sending command"}
@view_config(route_name="json_update_poc_address", renderer="prettyjson", request_method='POST', permission="edit")
def json_update_poc_address(request):
try:
new_addr = request.json_body['pocIPAddress']
upsert = request.db['pocConfiguration'].update_one({"_id": "pocIPAddress"}, {"$set": {'pocIPAddress': new_addr}}, upsert=True)
return {"status": "OK"}
except KeyError:
return {"status": "failure"}
@view_config(route_name="json_users", renderer="prettyjson", request_method='POST', permission="edit")
def json_newuser(request):
jsb = request.json_body
if request.db['users'].count({"username": jsb['username']}) > 0:
fail_reason = "There is already a user with this username"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['username']) < 5:
fail_reason = "The username must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['password']) < 5:
fail_reason = "The password must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
else:
set_return = set_password(request, jsb['username'], jsb['password'])
return {'status': "OK"}
@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='GET')
def json_getuser(request):
user_list = []
users = list(request.db['users'].find())
for user in users:
user_list.append(user['username'])
return {'users': user_list}
@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='DELETE')
def json_deleteuser(request):
request.db['users'].remove({'username': request.json_body['username']})
user_list = []
users = list(request.db['users'].find())
for user in users:
user_list.append(user['username'])
return {'users': user_list}
@view_config(route_name="json_users", renderer="prettyjson", request_method='PUT', permission="edit")
def json_updateuser(request):
jsb = request.json_body
if len(jsb['username']) < 5:
fail_reason = "The username must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['password']) < 5:
fail_reason = "The password must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
else:
set_return = set_password(request, jsb['username'], jsb['password'])
return {'status': "OK"}
@view_config(route_name="json_setpoints", renderer="prettyjson", request_method='GET', permission='edit')
def json_setpoints(request):
return {'setpoints': list(request.db['setpoints'].find())}
@view_config(route_name="json_setpoints", renderer="prettyjson", request_method='POST', permission='edit')
def json_setpoints_post(request):
jsb = request.json_body
try:
name = jsb['name']
value = jsb['value']
upsert = request.db['setpoints'].update_one({"name": name}, {"$set": {'value': value, 'storedBy': request.authenticated_userid, 'lastStored': datetime.utcnow()}}, upsert=True)
address = get_poc_address(request) or 'localhost'
url = "http://{}:8000/update?setpoint={}".format(address, name)
print(url)
r = requests.get(url)
update_status = r.text if r.status_code == 200 else {"status": "failure sending command"}
return {"updated": list(request.db['setpoints'].find_one({"name": name})), 'status': update_status}
except KeyError:
return {"status": "bad reqest"}
runModes = {0: 'poc', 1: 'manual', 2: 'timer'}
@view_config(route_name="json_mode", renderer="prettyjson", request_method='POST', permission='edit')
def json_mode_post(request):
jsb = request.json_body
try:
mode = jsb['mode']
upsert = request.db['setpoints'].update_one({"name": "runMode"}, {"$set": {'value': mode, 'storedBy': request.authenticated_userid, 'lastStored': datetime.utcnow()}}, upsert=True)
address = get_poc_address(request) or 'localhost'
url = "http://{}:8000/mode?mode={}&user={}".format(address, runModes[mode], request.authenticated_userid)
print(url)
r = requests.get(url)
update_status = r.text if r.status_code == 200 else {"status": "failure sending command"}
return {"updated": request.db['setpoints'].find_one({"name": "runMode"}), 'status': update_status}
except KeyError:
return {"status": "bad reqest"}

View File

@@ -1,282 +0,0 @@
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}

View File

@@ -1,138 +0,0 @@
from pyramid.view import view_config
import requests
from datetime import datetime
def get_poc_address(request):
addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"}))
address = False
if len(addr_obj) > 0:
address = addr_obj[0]['pocIPAddress']
return address
@view_config(route_name="poc_updateconfig_json", renderer="prettyjson", request_method='POST', permission="edit")
def json_updateconfig(request):
conv_to_float = [
'deltaT',
'pumpDiameter',
'fluidGradient',
'tubingID',
'tubingOD',
'tubingAnchorDepth',
'structuralRating',
'stuffingBoxFriction',
'tubingHeadPressure'
]
t_conv_to_float = ['length', 'diameter', 'dampingFactor']
jsb = request.json_body
new_config = {}
new_config['timestamp'] = datetime.utcnow()
new_config['storedBy'] = request.authenticated_userid
new_config['wellName'] = jsb['wellName']
new_config['tapers'] = []
for p in conv_to_float:
new_config[p] = float(jsb[p])
for t_i in range(0, len(jsb['tapers'])):
t = {}
for p in t_conv_to_float:
t[p] = float(jsb['tapers'][t_i][p])
t['material'] = jsb['tapers'][t_i]['material']
new_config['tapers'].append(t)
result = request.db['wellConfiguration'].insert(new_config)
addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"}))
address = 'localhost'
if len(addr_obj) > 0:
address = addr_obj[0]['pocIPAddress']
update_url = "http://{}:8000/config?update=true".format(address)
r = requests.get(update_url)
pocCmdSts = "OK" if r.status_code == 200 else "failed"
return {'new_config': request.json_body, 'stored_result': result, 'updated': pocCmdSts}
@view_config(route_name="poc_cmd_json", renderer="prettyjson", permission="edit")
def json_cmd(request):
print("got here")
action = request.matchdict['action']
address = get_poc_address(request) or 'localhost'
java_url = {}
java_url['start'] = "http://{}:8000/command?cmd=start&user={}".format(address, request.authenticated_userid)
java_url['stop'] = "http://{}:8000/command?cmd=stop&user={}".format(address, request.authenticated_userid)
# java_url['shake'] = "http://{}:8000/shake".format(address)
r = requests.get(java_url[action])
return r.text if r.status_code == 200 else {"status": "failure sending command"}
@view_config(route_name="poc_shake_json", renderer="prettyjson", permission="view")
def json_shake(request):
address = get_poc_address(request) or 'localhost'
url = "http://{}:8000/shake".format(address)
r = requests.get(url)
return r.text if r.status_code == 200 else {"status": "failure sending command"}
@view_config(route_name="poc_updatepocaddress_json", renderer="prettyjson", request_method='POST', permission="edit")
def json_update_poc_address(request):
try:
new_addr = request.json_body['pocIPAddress']
upsert = request.db['pocConfiguration'].update_one({"_id": "pocIPAddress"}, {"$set": {'pocIPAddress': new_addr}}, upsert=True)
return {"status": "OK"}
except KeyError:
return {"status": "failure"}
@view_config(route_name='poc_setpoints', renderer='templates/setpoints.jinja2', permission='edit')
def setpoints(request):
return {"navgroup": "setpoints"}
@view_config(route_name="poc_setpoints_json", renderer="prettyjson", request_method='GET', permission='edit')
def json_setpoints(request):
return {'setpoints': list(request.db['setpoints'].find())}
@view_config(route_name="poc_setpoints_json", renderer="prettyjson", request_method='POST', permission='edit')
def json_setpoints_post(request):
jsb = request.json_body
try:
name = jsb['name']
value = jsb['value']
upsert = request.db['setpoints'].update_one({"name": name}, {"$set": {'value': value, 'storedBy': request.authenticated_userid, 'lastStored': datetime.utcnow()}}, upsert=True)
address = get_poc_address(request) or 'localhost'
url = "http://{}:8000/update?setpoint={}".format(address, name)
print(url)
r = requests.get(url)
update_status = r.text if r.status_code == 200 else {"status": "failure sending command"}
return {"updated": list(request.db['setpoints'].find_one({"name": name})), 'status': update_status}
except KeyError:
return {"status": "bad reqest"}
runModes = {0: 'poc', 1: 'manual', 2: 'timer'}
@view_config(route_name="poc_mode_json", renderer="prettyjson", request_method='POST', permission='edit')
def json_mode_post(request):
jsb = request.json_body
try:
mode = jsb['mode']
upsert = request.db['setpoints'].update_one({"name": "runMode"}, {"$set": {'value': mode, 'storedBy': request.authenticated_userid, 'lastStored': datetime.utcnow()}}, upsert=True)
address = get_poc_address(request) or 'localhost'
url = "http://{}:8000/mode?mode={}&user={}".format(address, runModes[mode], request.authenticated_userid)
print(url)
r = requests.get(url)
update_status = r.text if r.status_code == 200 else {"status": "failure sending command"}
return {"updated": request.db['setpoints'].find_one({"name": "runMode"}), 'status': update_status}
except KeyError:
return {"status": "bad reqest"}

View File

@@ -1,30 +0,0 @@
from pyramid.view import view_config
from math import ceil
from .pagination import Pagination
@view_config(route_name="runstatus", renderer="templates/runstatus.jinja2")
@view_config(route_name="runstatus_json", renderer="prettyjson")
@view_config(route_name="runstatus_page_json", renderer="prettyjson")
def run_status(request):
page_num = 1
try:
page_num = int(request.matchdict['page_num'])
except KeyError:
pass
num_per_page = 100
num_cards = request.db['runStatus'].count()
pages = ceil(num_cards / num_per_page)
runStatuses = list(request.db['runStatus'].find().sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page))
return {'navgroup': 'runstatus', 'data': runStatuses, 'pagination': Pagination(page_num, num_per_page, num_cards)}
@view_config(route_name="runstatus_now_json", renderer="prettyjson")
def json_runstatusnow(request):
status = False
try:
status = list(request.db['runStatus'].find().sort("timestamp", -1).limit(1))[0]
except IndexError:
pass
return {'runstatus': status}

View File

@@ -1,5 +1,4 @@
from pyramid.security import Allow, Everyone, Authenticated
from passlib.apps import custom_app_context as poc_pwd_context
class UserLoginFactory(object):
@@ -9,20 +8,3 @@ class UserLoginFactory(object):
def __init__(self, request):
pass
def set_password(request, username, password):
password_hash = poc_pwd_context.encrypt(password)
request.db['users'].update_one({'username': username}, {"$set":{"username": username, "password": password_hash}}, upsert=True)
def check_password(request, username, password):
users = list(request.db['users'].find({'username': username}))
if len(users) > 0:
this_user = users[0]
# is it cleartext?
if password == this_user['password']:
set_password(request, username, password)
return check_password(request, username, password)
return poc_pwd_context.verify(password, this_user['password'])

View File

@@ -86,30 +86,23 @@ function drawChart(data){
var graph_data = [] ;
var json_data = data.values;
var ctx = document.getElementById("valueChart");
var color_index = 0;
for (x in data.values){
var tagdata = data.values[x];
for (var i = 0; i < json_data.length; i++){
var newObj = {
label: x,
label: json_data[i].tagname,
fill: false,
data: [],
lineTension: 0.05,
borderColor: color_scale[color_index % color_scale.length],
borderColor: color_scale[i % color_scale.length],
pointRadius: 2
};
for (var j = 0; j < tagdata.values.length; j++){
}
for(var j = 0; j < json_data[i].timestamps.length; j++){
newObj.data.push({
x: tagdata.values[j].timestamp,
y: tagdata.values[j].tagvalue
x: json_data[i].timestamps[j],
y: json_data[i].currentValues[j]
});
}
graph_data.push(newObj);
color_index++;
}
scatterChart = new Chart(ctx, {
type: 'line',
responsive: true,
@@ -137,96 +130,33 @@ function drawSingleGraph(data){
console.log("Destroying existing chart");
scatterChart.destroy();
}
var tag = data.tag[data.tagname];
console.log(tag);
var graph_data = [];
var values = data.values;
var ctx = document.getElementById("myChart");
var color_index = 0;
// Current Values
var currentValues = {
label: "Value",
fill: false,
data: [],
lineTension: 0.05,
borderColor: color_scale[color_index % color_scale.length]
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);
}
for (var i = 0; i < tag.values.length; i++){
currentValues.data.push({x: tag.values[i].timestamp, y: tag.values[i].tagvalue});
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]
});
}
}
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[i].timestamp, y: tag.maxes[i].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[i].timestamp, y: tag.mins[i].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[i].timestamp, y: tag.averages[i].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[i].timestamp, y: tag.totals[i].maxValue});
}
graph_data.push(totalValues)
color_index++;
console.log(graph_data);
scatterChart = new Chart(ctx, {
type: 'line',
data: {

View File

@@ -23,6 +23,11 @@
<th class="allcaps">Name</th>
<th class="allcaps"></th>
<th class="allcaps">Value</th>
<th class="allcaps">Timestamp</th>
<!-- <th>Max</th>
<th>Min</th>
<th>Average</th>
<th>Total</th> -->
</tr>
</thead>
<tbody>
@@ -31,18 +36,19 @@
<tr>
<td><a href="/values/tag/{{t._id}}">{{t._id}}</a></td>
<td>
<button type="button" class="btn btn-default" title="{{t._id}}" data-container="body" data-toggle="popover" data-trigger="focus" data-placement="right" data-content="Max: {{t.maxValue | round(3)}} {{t.units}}<br \>
Min: {{t.minValue | round(3)}} {{t.units}}<br \>
{% if t.useAverage %}
Average: {{t.averageValue | round(3)}} {{t.units}}<br \>
{% endif %}
{% if t.useTotal %}
Total: {{t.totalValue | round(3)}} {{t.units}}
{% endif %}">
<button type="button" class="btn btn-default" title="{{t._id}}" data-container="body" data-toggle="popover" data-trigger="focus" data-placement="right" data-content="Max: {{t.max | round(3)}}<br \>
Min: {{t.min | round(3)}}<br \>
Average: {{t.average | round(3)}}<br \>
Total: {{t.total | round(3)}}">
Details
</button>
</td>
<td>{{t.currentValue | round(3)}} {{t.units}}</td>
<td>{{t.value | round(3)}}</td>
<td>{{t.timestamp | datetime('short')}}</td>
<!-- <td>{{t.max | round(3)}}</td>
<td>{{t.min | round(3)}}</td>
<td>{{t.average | round(3)}}</td>
<td>{{t.total | round(3)}}</td> -->
</tr>
{% endfor %}

View File

@@ -67,9 +67,9 @@
<li {% if (navgroup == 'setpoints') %}class="active"{% endif %}><a href="/setpoints">Setpoints</a></li>
<li {% if (navgroup == 'config') %}class="active"{% endif %}><a href="/config">Well Setup</a></li>
<li><a href="/register">{{request.authenticated_userid}}</a></li>
<li><form class="navbar-form"><div class="form-group"><a href="{{request.route_url('users_auth',action='out')}}" class="btn btn-warning">Sign Out</a></div></form></li>
<li><form class="navbar-form"><div class="form-group"><a href="{{request.route_url('auth',action='out')}}" class="btn btn-warning">Sign Out</a></div></form></li>
{% else %}
<form action="{{request.route_url('users_auth',action='in')}}" method="post" class="form-inline navbar-form">
<form action="{{request.route_url('auth',action='in')}}" method="post" class="form-inline navbar-form">
<div class="form-group">
<input type="text" name="username" class="form-control" placeholder="Username">
</div>

View File

@@ -47,8 +47,6 @@ $.ajax({
success: drawSingleSlider
});
console.log("/json/values/tag/" + tagName + "/between/" + start + "/" + end);
$.ajax({
dataType: 'json',
url: "/json/values/tag/" + tagName + "/between/" + start + "/" + end,

View File

@@ -15,17 +15,19 @@
<th>Min</th>
<th>Average</th>
<th>Total</th>
<th>Last Stored</th>
</tr>
</thead>
<tbody>
{% for t in current_values %}
{% for t in current_tag_values %}
<tr>
<td><a href="/values/tag/{{t._id}}">{{t._id}}</a></td>
<td>{{t.currentValue | round(3)}} {{t.units}}</td>
<td>{{t.maxValue | round(3)}} {{t.units}}</td>
<td>{{t.minValue | round(3)}} {{t.units}}</td>
<td>{% if t.useAverage %}{{t.averageValue | round(3)}} {{t.units}}{% endif %}</td>
<td>{% if t.useTotal %}{{t.totalValue | round(3)}} {{t.units}}{% endif %}</td>
<td>{{t.value | round(3)}}</td>
<td>{{t.max | round(3)}}</td>
<td>{{t.min | round(3)}}</td>
<td>{{t.average | round(3)}}</td>
<td>{{t.total | round(3)}}</td>
<td>{{t.timestamp | datetime('medium')}}</td>
</tr>
{% endfor %}
</tbody>

View File

@@ -1,77 +0,0 @@
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound
from pyramid.security import remember, forget
from .security import check_password, set_password
@view_config(route_name="users_auth")
def sign_in_out(request):
username = request.POST.get('username')
if username:
if check_password(request, username, request.POST.get('password')):
headers = remember(request, username)
else:
headers = forget(request)
else:
headers = forget(request)
return HTTPFound(location=request.route_url('home'), headers=headers)
@view_config(route_name='users_register', renderer='templates/register.jinja2', permission="edit")
def register(request):
return {"navgroup": "user"}
@view_config(route_name="users_json", renderer="prettyjson", request_method='POST', permission="edit")
def json_newuser(request):
jsb = request.json_body
if request.db['users'].count({"username": jsb['username']}) > 0:
fail_reason = "There is already a user with this username"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['username']) < 5:
fail_reason = "The username must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['password']) < 5:
fail_reason = "The password must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
else:
set_return = set_password(request, jsb['username'], jsb['password'])
return {'status': "OK"}
@view_config(route_name="users_json", renderer="prettyjson", permission="edit", request_method='GET')
def json_getuser(request):
user_list = []
users = list(request.db['users'].find())
for user in users:
user_list.append(user['username'])
return {'users': user_list}
@view_config(route_name="users_json", renderer="prettyjson", permission="edit", request_method='DELETE')
def json_deleteuser(request):
request.db['users'].remove({'username': request.json_body['username']})
user_list = []
users = list(request.db['users'].find())
for user in users:
user_list.append(user['username'])
return {'users': user_list}
@view_config(route_name="users_json", renderer="prettyjson", request_method='PUT', permission="edit")
def json_updateuser(request):
jsb = request.json_body
if len(jsb['username']) < 5:
fail_reason = "The username must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['password']) < 5:
fail_reason = "The password must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
else:
set_return = set_password(request, jsb['username'], jsb['password'])
return {'status': "OK"}

108
pocwww/view_helpers.py Normal file
View File

@@ -0,0 +1,108 @@
from datetime import datetime, timedelta
from math import ceil
from passlib.apps import custom_app_context as poc_pwd_context
from dateutil import tz
from .pagination import Pagination
from_zone = tz.tzutc()
to_zone = tz.tzlocal()
def get_lastest_tag_values(request):
latest_tag_values = []
latesttag_agg = request.db['wellData'].aggregate([
{
'$sort': {"tagname": 1, "timestamp": 1}
},
{
'$group': {
'_id': "$tagname",
'timestamp': {'$last': "$timestamp"},
'value': {'$last': "$currentValue"},
'max': {'$last': "$maxDailyValue"},
'min': {'$last': "$minDailyValue"},
'average': {'$last': "$dailyAverage"},
'total': {'$last': "$dailyTotal"}
}
}
])
for t in latesttag_agg:
latest_tag_values.append(t)
return latest_tag_values
def get_latest_card(request):
try:
latest_card = list(request.db['cards'].find().sort("timestamp", -1).limit(1))[0]
return latest_card
except IndexError:
return []
def card_page(request):
page_num = 1
try:
page_num = int(request.matchdict['page_num'])
except KeyError:
pass
cards_date_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
try:
cards_date_start = datetime.strptime(request.matchdict['cards_date'], "%Y-%m-%d")
except KeyError:
pass
cards_date_end = cards_date_start + timedelta(days=1)
num_per_page = 100
num_cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).count()
pages = ceil(num_cards / num_per_page)
cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page)
return {'cards': list(cards), 'pagination': Pagination(page_num, num_per_page, num_cards), 'cards_date': cards_date_start.strftime("%Y-%m-%d"), 'navgroup': 'cards'}
def get_all_dates_with_cards(request):
datelist = []
dateagg = request.db['cards'].aggregate([
{"$group": {
"_id": {"$concat": [
{"$substr": [{"$year": "$timestamp"}, 0, 4]},
"-",
{"$substr": [{"$month": "$timestamp"}, 0, 2]},
"-",
{"$substr": [{"$dayOfMonth": "$timestamp"}, 0, 2]},
]},
"count": {"$sum": 1}
}},
{"$sort": {"_id": -1}}
])
for d in dateagg:
datelist.append({'count': d['count'], 'date': datetime.strptime(d['_id'], "%Y-%m-%d").date()})
return list(datelist)
def get_poc_address(request):
addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"}))
address = False
if len(addr_obj) > 0:
address = addr_obj[0]['pocIPAddress']
return address
def set_password(request, username, password):
password_hash = poc_pwd_context.encrypt(password)
request.db['users'].update_one({'username': username}, {"$set":{"username": username, "password": password_hash}}, upsert=True)
def check_password(request, username, password):
users = list(request.db['users'].find({'username': username}))
if len(users) > 0:
this_user = users[0]
# is it cleartext?
if password == this_user['password']:
set_password(request, username, password)
return check_password(request, username, password)
return poc_pwd_context.verify(password, this_user['password'])

172
pocwww/views.py Normal file
View File

@@ -0,0 +1,172 @@
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound
from pyramid.security import remember, forget
from datetime import datetime, timedelta
from math import ceil
from .view_helpers import *
@view_config(route_name='home', renderer='templates/dashboard.jinja2')
@view_config(route_name="json_snapshot", renderer="prettyjson")
def my_view(request):
return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': get_lastest_tag_values(request), 'card': get_latest_card(request)}
@view_config(route_name='cards', renderer='templates/datelist.jinja2')
@view_config(route_name='json_cards', renderer='prettyjson')
def cards(request):
return {'datelist': get_all_dates_with_cards(request), 'navgroup': 'cards'}
@view_config(route_name='cards_page', renderer='templates/cardlist.jinja2')
@view_config(route_name='cards_date', renderer='templates/cardlist.jinja2')
@view_config(route_name='json_cards_date', renderer='prettyjson')
@view_config(route_name='json_cards_page', renderer='prettyjson')
def cards_page(request):
cp = card_page(request)
cp['datelist'] = get_all_dates_with_cards(request)
return cp
@view_config(route_name='card_single', renderer='templates/cardsingle.jinja2')
@view_config(route_name='json_card_single', renderer='prettyjson')
def card_single(request):
card = {}
try:
card = list(request.db['cards'].find({"strokeNumber": int(request.matchdict['stroke_number'])}))[0]
except IndexError:
pass
datepage_url = request.referrer.split("/")[3:]
page_num = 1
carddate = ""
if len(datepage_url) > 2:
page_num = int(datepage_url[2])
if len(datepage_url) > 1:
carddate = datepage_url[1]
return {"card": card, 'navgroup': 'cards', 'datelist': get_all_dates_with_cards(request), 'date': carddate, 'datepage': page_num}
@view_config(route_name='values_all', renderer="templates/valuesall.jinja2")
@view_config(route_name='json_values_all', renderer='prettyjson')
def values_all(request):
return {'navgroup': 'values', 'current_tag_values': get_lastest_tag_values(request)}
@view_config(route_name="values_tag", renderer="templates/values_single.jinja2")
def values_tag(request):
tagname = request.matchdict['tagname']
return {'navgroup': 'values', 'tagname': tagname}
@view_config(route_name="gaugeoff_all", renderer="templates/gaugeoff_all.jinja2")
@view_config(route_name="json_gaugeoff_all", renderer="prettyjson")
def gaugeoff_all(request):
gaugeoff_list = []
dateagg = list(request.db['gaugeOff'].aggregate(
[
{
'$project': {
'yearMonthDay': {'$dateToString': {'format': "%Y-%m-%d", 'date': "$timestamp"}},
'tagname': 1,
'dailyTotal': 1,
'dailyAverage': 1,
'maxDailyValue': 1,
'minDailyValue': 1,
'currentValue': 1
}
},
{
'$group': {
'_id': "$yearMonthDay",
'tags': {'$push': {'name': "$tagname"}},
'totals': {'$push': {'total': "$dailyTotal"}},
'averages': {'$push': {'average': "$dailyAverage"}},
'max': {'$push': {'max': "$maxDailyValue"}},
'min': {'$push': {'min': "$minDailyValue"}},
'last': {'$push': {'last': "$currentValue"}}
}
}
]))
for d in dateagg:
newGO = {'date': datetime.strptime(d["_id"], '%Y-%m-%d'), 'tags': {}}
for i in range(0, len(d['tags'])):
newTagObj = {
"max": d['max'][i]['max'],
"min": d['min'][i]['min'],
"last": d['last'][i]['last'],
"total": d['totals'][i]['total'],
"average": d['averages'][i]['average'],
}
newGO['tags'][d['tags'][i]['name']] = newTagObj
gaugeoff_list.append(newGO)
return {'navgroup': 'gaugeoff', 'data': gaugeoff_list}
@view_config(route_name="fluidshots_all", renderer="templates/fluidshots.jinja2")
@view_config(route_name="json_fluidshots_all", renderer="prettyjson")
def fluidshots_all(request):
fluidshots = list(request.db['fluidShots'].find())
return {'navgroup': 'fluidshots', 'data': fluidshots}
@view_config(route_name="welltests_all", renderer="templates/welltests.jinja2")
@view_config(route_name="json_welltests_all", renderer="prettyjson")
def welltests_all(request):
welltests = list(request.db['wellTests'].find())
return {'navgroup': 'welltests', 'data': welltests}
@view_config(route_name="runstatus", renderer="templates/runstatus.jinja2")
@view_config(route_name="json_runstatus", renderer="prettyjson")
@view_config(route_name="json_runstatus_page", renderer="prettyjson")
def run_status(request):
page_num = 1
try:
page_num = int(request.matchdict['page_num'])
except KeyError:
pass
num_per_page = 100
num_cards = request.db['runStatus'].count()
pages = ceil(num_cards / num_per_page)
runStatuses = list(request.db['runStatus'].find().sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page))
return {'navgroup': 'runstatus', 'data': runStatuses, 'pagination': Pagination(page_num, num_per_page, num_cards)}
@view_config(route_name="config", renderer="templates/config.jinja2", permission="edit")
@view_config(route_name="json_config", renderer="prettyjson", permission="edit")
def well_config(request):
current_configuration = list(request.db['wellConfiguration'].find().sort("timestamp", -1).limit(1))[0]
return {'navgroup': 'config', 'config': current_configuration}
@view_config(route_name="admin", renderer="templates/admin.jinja2", permission="edit")
def admin_view(request):
address = get_poc_address(request) or 'localhost'
return {'navgroup': 'admin', 'pocIPAddress': address}
@view_config(route_name="auth")
def sign_in_out(request):
username = request.POST.get('username')
if username:
if check_password(request, username, request.POST.get('password')):
headers = remember(request, username)
else:
headers = forget(request)
else:
headers = forget(request)
return HTTPFound(location=request.route_url('home'), headers=headers)
@view_config(route_name='register',
renderer='templates/register.jinja2', permission="edit")
def register(request):
return {"navgroup": "user"}
@view_config(route_name='setpoints', renderer='templates/setpoints.jinja2', permission='edit')
def setpoints(request):
return {"navgroup": "setpoints"}

View File

@@ -1,8 +0,0 @@
from pyramid.view import view_config
@view_config(route_name="welltests_all", renderer="templates/welltests.jinja2")
@view_config(route_name="welltests_all_json", renderer="prettyjson")
def welltests_all(request):
welltests = list(request.db['wellTests'].find())
return {'navgroup': 'welltests', 'data': welltests}

View File

@@ -17,7 +17,6 @@ requires = [
'requests',
'passlib',
'python-dateutil',
'pytz',
]
tests_require = [