Compare commits
1 Commits
master
...
POCONSOLE-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53ddf5fab4 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,3 +5,7 @@ sails/.tmp
|
||||
.remote-sync.json
|
||||
database.db
|
||||
venv/
|
||||
.vscode/
|
||||
pyr_test/env/lib/python2.7/site-packages/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl
|
||||
pyr_test/env/
|
||||
pyr_test/hp_webserver/poconsole.egg-info/
|
||||
|
||||
49
pyr_test/hp_webserver/development.ini
Normal file
49
pyr_test/hp_webserver/development.ini
Normal file
@@ -0,0 +1,49 @@
|
||||
[app:main]
|
||||
use = egg:poconsole
|
||||
pyramid.reload_templates = true
|
||||
pyramid.includes =
|
||||
pyramid_debugtoolbar
|
||||
pyramid_tm
|
||||
|
||||
sqlalchemy.url = sqlite:///%(here)s/poconsole.sqlite
|
||||
|
||||
[server:main]
|
||||
use = egg:pyramid#wsgiref
|
||||
host = 0.0.0.0
|
||||
port = 6543
|
||||
|
||||
# Begin logging configuration
|
||||
|
||||
[loggers]
|
||||
keys = root, poconsole, sqlalchemy.engine.base.Engine
|
||||
|
||||
[logger_poconsole]
|
||||
level = DEBUG
|
||||
handlers =
|
||||
qualname = poconsole
|
||||
|
||||
[handlers]
|
||||
keys = console
|
||||
|
||||
[formatters]
|
||||
keys = generic
|
||||
|
||||
[logger_root]
|
||||
level = INFO
|
||||
handlers = console
|
||||
|
||||
[logger_sqlalchemy.engine.base.Engine]
|
||||
level = INFO
|
||||
handlers =
|
||||
qualname = sqlalchemy.engine.base.Engine
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
level = NOTSET
|
||||
formatter = generic
|
||||
|
||||
[formatter_generic]
|
||||
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
|
||||
|
||||
# End logging configuration
|
||||
35
pyr_test/hp_webserver/poconsole/__init__.py
Normal file
35
pyr_test/hp_webserver/poconsole/__init__.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from pyramid.config import Configurator
|
||||
|
||||
from sqlalchemy import engine_from_config
|
||||
|
||||
from .models import DBSession, Base
|
||||
|
||||
def main(global_config, **settings):
|
||||
engine = engine_from_config(settings, 'sqlalchemy.')
|
||||
DBSession.configure(bind=engine)
|
||||
Base.metadata.bind = engine
|
||||
|
||||
config = Configurator(settings=settings,
|
||||
root_factory='poconsole.models.Root')
|
||||
config.include('pyramid_chameleon')
|
||||
|
||||
# Configs
|
||||
config.add_route('configs', '/api/configs')
|
||||
config.add_route('config', '/api/configs/{_id}')
|
||||
|
||||
# Configs
|
||||
config.add_route('configs', '/api/configs')
|
||||
config.add_route('config', '/api/configs/{_id}')
|
||||
|
||||
# Device Types
|
||||
config.add_route('device_types', '/api/device_types')
|
||||
config.add_route('device_type', '/api/device_types/{_id}')
|
||||
|
||||
|
||||
config.add_route('wiki_view', '/')
|
||||
config.add_route('wikipage_add', '/add')
|
||||
config.add_route('wikipage_view', '/{uid}')
|
||||
config.add_route('wikipage_edit', '/{uid}/edit')
|
||||
config.add_static_view('deform_static', 'deform:static/')
|
||||
config.scan('.views')
|
||||
return config.make_wsgi_app()
|
||||
61
pyr_test/hp_webserver/poconsole/initalize_db.py
Normal file
61
pyr_test/hp_webserver/poconsole/initalize_db.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import os
|
||||
import sys
|
||||
import transaction
|
||||
|
||||
from sqlalchemy import engine_from_config
|
||||
|
||||
from pyramid.paster import (
|
||||
get_appsettings,
|
||||
setup_logging,
|
||||
)
|
||||
|
||||
from .models import (
|
||||
DBSession,
|
||||
Config,
|
||||
Device_type,
|
||||
Device,
|
||||
Doc,
|
||||
Tag,
|
||||
Tag_val,
|
||||
Card,
|
||||
GaugeOffVal,
|
||||
WellTest,
|
||||
Note,
|
||||
EventConfig,
|
||||
Event,
|
||||
RunStatus,
|
||||
FluidShot,
|
||||
BackupRestore,
|
||||
Base,
|
||||
)
|
||||
|
||||
|
||||
def usage(argv):
|
||||
cmd = os.path.basename(argv[0])
|
||||
print('usage: %s <config_uri>\n'
|
||||
'(example: "%s development.ini")' % (cmd, cmd))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
if len(argv) != 2:
|
||||
usage(argv)
|
||||
config_uri = argv[1]
|
||||
setup_logging(config_uri)
|
||||
settings = get_appsettings(config_uri)
|
||||
engine = engine_from_config(settings, 'sqlalchemy.')
|
||||
DBSession.configure(bind=engine)
|
||||
Base.metadata.create_all(engine)
|
||||
with transaction.manager:
|
||||
# Device Type Seeds
|
||||
device_type_CLX = Device_type(device_type='CLX')
|
||||
device_type_u800 = Device_type(device_type='Micro800')
|
||||
device_type_E300 = Device_type(device_type='E300')
|
||||
|
||||
DBSession.add(device_type_CLX)
|
||||
DBSession.add(device_type_u800)
|
||||
DBSession.add(device_type_E300)
|
||||
|
||||
# Device Seeds
|
||||
main_plc = Device(device_type_id=1, address="192.168.1.10")
|
||||
DBSession.add(main_plc)
|
||||
221
pyr_test/hp_webserver/poconsole/models.py
Normal file
221
pyr_test/hp_webserver/poconsole/models.py
Normal file
@@ -0,0 +1,221 @@
|
||||
from pyramid.security import Allow, Everyone
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
Integer,
|
||||
Text,
|
||||
String,
|
||||
Float,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
)
|
||||
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
from sqlalchemy.orm import (
|
||||
scoped_session,
|
||||
sessionmaker,
|
||||
relationship
|
||||
)
|
||||
|
||||
from zope.sqlalchemy import ZopeTransactionExtension
|
||||
|
||||
DBSession = scoped_session(
|
||||
sessionmaker(extension=ZopeTransactionExtension()))
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
# class Page(Base):
|
||||
# __tablename__ = 'wikipages'
|
||||
# uid = Column(Integer, primary_key=True)
|
||||
# title = Column(Text, unique=True)
|
||||
# body = Column(Text)
|
||||
|
||||
class Config(Base):
|
||||
__tablename__ = "configs"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
parameter = Column(String(100), unique=True)
|
||||
val = Column(String(100), unique=True)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Device_type(Base):
|
||||
__tablename__ = "device_types"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
device_type = Column(String(64))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Device(Base):
|
||||
__tablename__ = "devices"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
device_type_id = Column(Integer, ForeignKey('device_types._id'))
|
||||
device_type = relationship(Device_type, primaryjoin=device_type_id == Device_type._id)
|
||||
address = Column(String(256))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Doc(Base):
|
||||
__tablename__ = "docs"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
name = Column(String(256))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Tag(Base):
|
||||
__tablename__ = "tags"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
name = Column(String(64))
|
||||
tag = Column(String(128))
|
||||
tag_category = Column(String(128))
|
||||
device_id = Column(Integer, ForeignKey('devices._id'))
|
||||
device = relationship(Device)
|
||||
description = Column(String(64))
|
||||
data_type = Column(String(64))
|
||||
change_threshold = Column(Float)
|
||||
guarantee_sec = Column(Integer)
|
||||
map_function = Column(String(64))
|
||||
units = Column(String(10))
|
||||
min_expected = Column(Float)
|
||||
max_expected = Column(Float)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Tag_val(Base):
|
||||
__tablename__ = "tag_vals"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
tag_id = Column(Integer, ForeignKey('tags._id'))
|
||||
tag = relationship(Tag)
|
||||
value = Column(Float)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Card(Base):
|
||||
__tablename__ = "cards"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
stroke_type = Column(String(32))
|
||||
stroke_number = Column(Integer)
|
||||
surf_pos = Column(Text)
|
||||
surf_lod = Column(Text)
|
||||
down_pos = Column(Text)
|
||||
down_lod = Column(Text)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class GaugeOffVal(Base):
|
||||
__tablename__ = "gauge_off"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
spm_average = Column(Float)
|
||||
downhole_gross_stroke_average = Column(Float)
|
||||
downhole_net_stroke_average = Column(Float)
|
||||
electricity_cost_total = Column(Float)
|
||||
fluid_level_average = Column(Float)
|
||||
full_card_production_total = Column(Float)
|
||||
inflow_rate_average = Column(Float)
|
||||
kWh_used_total = Column(Float)
|
||||
kWh_regen_total = Column(Float)
|
||||
lifting_cost_average = Column(Float)
|
||||
peak_pr_load = Column(Float)
|
||||
min_pr_load = Column(Float)
|
||||
percent_run = Column(Float)
|
||||
polished_rod_hp_average = Column(Float)
|
||||
pump_hp_average = Column(Float)
|
||||
production_total = Column(Float)
|
||||
pump_intake_pressure_average = Column(Float)
|
||||
surface_stroke_length_average = Column(Float)
|
||||
tubing_movement_average = Column(Float)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class WellTest(Base):
|
||||
__tablename__ = "well_tests"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
duration_hours = Column(Float)
|
||||
volume_h2o_actual = Column(Float)
|
||||
volume_oil_actual = Column(Float)
|
||||
volume_gas_actual = Column(Float)
|
||||
volume_h2o_projected = Column(Float)
|
||||
volume_oil_projected = Column(Float)
|
||||
volume_gas_projected = Column(Float)
|
||||
api_gravity_oil = Column(Float)
|
||||
spc_gravity_h2o = Column(Float)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Note(Base):
|
||||
__tablename__ = "notes"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
note_text = Column(String(256))
|
||||
author = Column(String(128))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class EventConfig(Base):
|
||||
__tablename__ = "event_configs"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
name = Column(String(64))
|
||||
event_type = Column(String(64))
|
||||
tag = Column(String(128))
|
||||
condition = Column(String(64))
|
||||
device_id = Column(Integer, ForeignKey('devices._id'))
|
||||
device = relationship(Device)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Event(Base):
|
||||
__tablename__ = "events"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
event_id = Column(Integer, ForeignKey('event_configs._id'))
|
||||
event = relationship(EventConfig)
|
||||
event_type = Column(String(64))
|
||||
event_condition = Column(String(64))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class RunStatus(Base):
|
||||
__tablename__ = "run_status_log"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
run_status = Column(String(64))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class FluidShot(Base):
|
||||
__tablename__ = "fluid_shots"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
pump_intake_pressure = Column(Float)
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class BackupRestore(Base):
|
||||
__tablename__ = "backup_restore"
|
||||
_id = Column(Integer, primary_key=True)
|
||||
tag = Column(String(128))
|
||||
tag_type = Column(String(128))
|
||||
device_id = Column(Integer, ForeignKey('devices._id'))
|
||||
device = relationship(Device)
|
||||
value = Column(String(128))
|
||||
created_on = Column(DateTime(), default=datetime.utcnow)
|
||||
updated_on = Column(DateTime(), default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
|
||||
class Root(object):
|
||||
__acl__ = [(Allow, Everyone, 'view'),
|
||||
(Allow, 'group:editors', 'edit')]
|
||||
|
||||
def __init__(self, request):
|
||||
pass
|
||||
0
pyr_test/hp_webserver/poconsole/tests.py
Normal file
0
pyr_test/hp_webserver/poconsole/tests.py
Normal file
128
pyr_test/hp_webserver/poconsole/views.py
Normal file
128
pyr_test/hp_webserver/poconsole/views.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import colander
|
||||
import deform.widget
|
||||
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
from pyramid.view import view_config
|
||||
|
||||
from .models import (
|
||||
DBSession,
|
||||
Config,
|
||||
Device_type,
|
||||
Device,
|
||||
Doc,
|
||||
Tag,
|
||||
Tag_val,
|
||||
Card,
|
||||
GaugeOffVal,
|
||||
WellTest,
|
||||
Note,
|
||||
EventConfig,
|
||||
Event,
|
||||
RunStatus,
|
||||
FluidShot,
|
||||
BackupRestore
|
||||
)
|
||||
|
||||
|
||||
class WikiPage(colander.MappingSchema):
|
||||
title = colander.SchemaNode(colander.String())
|
||||
body = colander.SchemaNode(
|
||||
colander.String(),
|
||||
widget=deform.widget.RichTextWidget()
|
||||
)
|
||||
|
||||
class ConfigCol(colander.MappingSchema):
|
||||
parameter = colander.SchemaNode(colander.string())
|
||||
val = colander.SchemaNode(colander.string())
|
||||
|
||||
|
||||
class ConfigViews(object):
|
||||
def __init__(self, request):
|
||||
self.request = request
|
||||
|
||||
@view_config(route_name='config', renderer='json')
|
||||
def get_config(self):
|
||||
id = int(self.request.matchdict['id'])
|
||||
config = DBSession.query(Config).filter_by(_id=id).one()
|
||||
return dict(config=config)
|
||||
|
||||
|
||||
class WikiViews(object):
|
||||
def __init__(self, request):
|
||||
self.request = request
|
||||
|
||||
@property
|
||||
def wiki_form(self):
|
||||
schema = WikiPage()
|
||||
return deform.Form(schema, buttons=('submit',))
|
||||
|
||||
@property
|
||||
def reqts(self):
|
||||
return self.wiki_form.get_widget_resources()
|
||||
|
||||
@view_config(route_name='wiki_view', renderer='wiki_view.pt')
|
||||
def wiki_view(self):
|
||||
pages = DBSession.query(Page).order_by(Page.title)
|
||||
return dict(title='Wiki View', pages=pages)
|
||||
|
||||
@view_config(route_name='wikipage_add',
|
||||
renderer='wikipage_addedit.pt')
|
||||
def wikipage_add(self):
|
||||
form = self.wiki_form.render()
|
||||
|
||||
if 'submit' in self.request.params:
|
||||
controls = self.request.POST.items()
|
||||
try:
|
||||
appstruct = self.wiki_form.validate(controls)
|
||||
except deform.ValidationFailure as e:
|
||||
# Form is NOT valid
|
||||
return dict(form=e.render())
|
||||
|
||||
# Add a new page to the database
|
||||
new_title = appstruct['title']
|
||||
new_body = appstruct['body']
|
||||
DBSession.add(Page(title=new_title, body=new_body))
|
||||
|
||||
# Get the new ID and redirect
|
||||
page = DBSession.query(Page).filter_by(title=new_title).one()
|
||||
new_uid = page.uid
|
||||
|
||||
url = self.request.route_url('wikipage_view', uid=new_uid)
|
||||
return HTTPFound(url)
|
||||
|
||||
return dict(form=form)
|
||||
|
||||
|
||||
@view_config(route_name='wikipage_view', renderer='wikipage_view.pt')
|
||||
def wikipage_view(self):
|
||||
uid = int(self.request.matchdict['uid'])
|
||||
page = DBSession.query(Page).filter_by(uid=uid).one()
|
||||
return dict(page=page)
|
||||
|
||||
|
||||
@view_config(route_name='wikipage_edit',
|
||||
renderer='wikipage_addedit.pt')
|
||||
def wikipage_edit(self):
|
||||
uid = int(self.request.matchdict['uid'])
|
||||
page = DBSession.query(Page).filter_by(uid=uid).one()
|
||||
|
||||
wiki_form = self.wiki_form
|
||||
|
||||
if 'submit' in self.request.params:
|
||||
controls = self.request.POST.items()
|
||||
try:
|
||||
appstruct = wiki_form.validate(controls)
|
||||
except deform.ValidationFailure as e:
|
||||
return dict(page=page, form=e.render())
|
||||
|
||||
# Change the content and redirect to the view
|
||||
page.title = appstruct['title']
|
||||
page.body = appstruct['body']
|
||||
url = self.request.route_url('wikipage_view', uid=uid)
|
||||
return HTTPFound(url)
|
||||
|
||||
form = self.wiki_form.render(dict(
|
||||
uid=page.uid, title=page.title, body=page.body)
|
||||
)
|
||||
|
||||
return dict(page=page, form=form)
|
||||
20
pyr_test/hp_webserver/setup.py
Normal file
20
pyr_test/hp_webserver/setup.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from setuptools import setup
|
||||
|
||||
requires = [
|
||||
'pyramid',
|
||||
'pyramid_chameleon',
|
||||
'deform',
|
||||
'sqlalchemy',
|
||||
'pyramid_tm',
|
||||
'zope.sqlalchemy'
|
||||
]
|
||||
|
||||
setup(name='poconsole',
|
||||
install_requires=requires,
|
||||
entry_points="""\
|
||||
[paste.app_factory]
|
||||
main = poconsole:main
|
||||
[console_scripts]
|
||||
initialize_poconsole_db = poconsole.initialize_db:main
|
||||
""",
|
||||
)
|
||||
Reference in New Issue
Block a user