Initial Commit
This commit is contained in:
67
python/solar_ww.py
Normal file
67
python/solar_ww.py
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Dec 8, 2015
|
||||
|
||||
@author: Patrick McDonagh
|
||||
'''
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
import sys
|
||||
from random import randint
|
||||
import time
|
||||
import MySQLdb
|
||||
import tuxeip
|
||||
|
||||
|
||||
#TUXEIP Connection to PLC
|
||||
from tuxeip import TuxEIP, LGX, LGX_REAL
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="SolarData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM SolarData.tags WHERE deleted = 0;"
|
||||
cur.execute(query)
|
||||
tags = cur.fetchall()
|
||||
# ((1L, 'DC_Bus_Voltage', datetime.datetime(2015, 12, 8, 16, 2, 32), 'V', 0L), (2L, 'Output_Frequency', datetime.datetime(2015, 12, 8, 16, 31, 12), 'Hz', 0L))
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = "192.168.1.13" # MAKE THIS A db VALUE
|
||||
|
||||
tagList = [];
|
||||
if len(tags) > 0:
|
||||
for t in tags:
|
||||
tagList.append({"id":int(t[0]), "name":t[1], "val":None, "lastVal":None});
|
||||
|
||||
try:
|
||||
tux = TuxEIP(libpath="/usr/lib/libtuxeip.so")
|
||||
sess = tux.OpenSession(PLC_IP_ADDRESS)
|
||||
reg = tux.RegisterSession(sess)
|
||||
conn = tux.ConnectPLCOverCNET(sess, LGX, 1, 100, 123, randint(0,9999), 123, 321, 100, 5000, 1, '01')
|
||||
|
||||
while True:
|
||||
for r in tagList:
|
||||
r["val"] = tux.ReadLGXDataAsFloat(sess, conn, r['name'], 1)[0]
|
||||
print("{0} - {1}".format(r["name"], r["val"]))
|
||||
if not r["val"] == r["lastVal"]:
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="SolarData")
|
||||
cur = db.cursor()
|
||||
aQuery = """INSERT INTO SolarData.values (tagID, val) VALUES ('%d', '%f');"""%(r["id"], float(r["val"]))
|
||||
print(aQuery)
|
||||
storeVal = cur.execute(aQuery)
|
||||
db.commit()
|
||||
db.close()
|
||||
r["lastVal"] = r["val"]
|
||||
|
||||
time.sleep(10)
|
||||
except Exception as err:
|
||||
print err
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
276
python/tuxeip.py
Normal file
276
python/tuxeip.py
Normal file
@@ -0,0 +1,276 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
# Copyright (C) 2014 Gayner Technical Services Pty Ltd
|
||||
|
||||
from ctypes import *
|
||||
|
||||
# PLC TYPES
|
||||
Unknow=0
|
||||
PLC=1
|
||||
SLC500=2
|
||||
LGX=3
|
||||
|
||||
# EIP DATA TYPES
|
||||
PLC_BIT=1
|
||||
PLC_BIT_STRING=2
|
||||
PLC_BYTE_STRING=3
|
||||
PLC_INTEGER=4
|
||||
PLC_TIMER=5
|
||||
PLC_COUNTER=6
|
||||
PLC_CONTROL=7
|
||||
PLC_FLOATING=8
|
||||
PLC_ARRAY=9
|
||||
PLC_ADRESS=15
|
||||
PLC_BCD=16
|
||||
|
||||
# LOGIX DATA TYPES
|
||||
LGX_BOOL=0xC1
|
||||
LGX_BITARRAY=0xD3
|
||||
LGX_SINT=0xC2
|
||||
LGX_INT=0xC3
|
||||
LGX_DINT=0xC4
|
||||
LGX_REAL=0xCA
|
||||
|
||||
class Eip_Session(Structure):
|
||||
_fields_ = [
|
||||
('sock',c_int),
|
||||
('Session_Handle', c_uint),
|
||||
('Sender_ContextL',c_int),
|
||||
('Sender_ContextH',c_int),
|
||||
('timeout', c_int),
|
||||
('references', c_int),
|
||||
('Data', c_void_p),
|
||||
]
|
||||
|
||||
class Eip_Connection(Structure):
|
||||
_fields_ = [
|
||||
('Eip_Session', Eip_Session),
|
||||
('references', c_int),
|
||||
('Data', c_void_p),
|
||||
('ConnectionSerialNumber', c_uint),
|
||||
('OriginatorVendorID', c_uint),
|
||||
('OriginatorSerialNumber', c_int),
|
||||
('OT_ConnID', c_int),
|
||||
('TO_ConnID', c_int),
|
||||
('packet', c_short),
|
||||
('Path_size', c_byte)
|
||||
]
|
||||
|
||||
class Eip_PLC_Read(Structure):
|
||||
_fields_ = [
|
||||
('type', c_int),
|
||||
('Varcount', c_int),
|
||||
('totalise', c_int),
|
||||
('elementsize', c_int),
|
||||
('mask', c_uint),
|
||||
]
|
||||
|
||||
class TuxEIPException(Exception):
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
class TuxEIP:
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.__libpath = kwargs.get("libpath", "libtuxeip.dylib")
|
||||
self.__tuxeip = CDLL(self.__libpath)
|
||||
self.__tuxeip._cip_err_msg.restype = c_char_p
|
||||
|
||||
def __del__(self):
|
||||
del self.__tuxeip
|
||||
|
||||
def OpenSession(self, slaveip_, slaveport_=44818, slavetimeout_=1000):
|
||||
self.__tuxeip._OpenSession.restype = POINTER(Eip_Session)
|
||||
|
||||
# Convert params to C types
|
||||
slaveip = c_char_p(slaveip_)
|
||||
slaveport = c_int(slaveport_)
|
||||
slavetimeout = c_int(slavetimeout_)
|
||||
|
||||
session = self.__tuxeip._OpenSession(slaveip, slaveport, slavetimeout)
|
||||
|
||||
#print self.__tuxeip._cip_err_msg, self.__tuxeip._cip_errno, self.__tuxeip._cip_ext_errno
|
||||
|
||||
if bool(session) == False:
|
||||
raise TuxEIPException("Could not open session to " + str(slaveip) + ":" + str(slaveport))
|
||||
|
||||
return session
|
||||
|
||||
def RegisterSession(self, sess_):
|
||||
self.__tuxeip._RegisterSession.restype = c_int
|
||||
reg = self.__tuxeip._RegisterSession(sess_)
|
||||
|
||||
if reg != False:
|
||||
raise TuxEIPException("Could not register session")
|
||||
|
||||
return reg
|
||||
|
||||
def ConnectPLCOverCNET(self, sess_, plctype_, priority_, timeoutticks_, connid_, conserial_,
|
||||
vendorid_, serialnum_, timeoutmult_, rpi_, transport_, slavepath_):
|
||||
# Convert params to C types
|
||||
priority = c_byte(priority_)
|
||||
timeoutticks = c_byte(timeoutticks_)
|
||||
connid = c_uint(connid_)
|
||||
conserial = c_ushort(conserial_)
|
||||
vendorid = c_ushort(vendorid_)
|
||||
serialnum = c_uint(serialnum_)
|
||||
timeutmult = c_byte(timeoutmult_)
|
||||
rpi = c_uint(rpi_)
|
||||
transport = c_byte(transport_)
|
||||
slavepath = c_char_p(slavepath_)
|
||||
pathlength = len(slavepath_)
|
||||
|
||||
self.__tuxeip._ConnectPLCOverCNET.restype = POINTER(Eip_Connection)
|
||||
|
||||
connection = self.__tuxeip._ConnectPLCOverCNET(
|
||||
sess_,
|
||||
plctype_,
|
||||
priority,
|
||||
timeoutticks,
|
||||
connid,
|
||||
conserial,
|
||||
vendorid,
|
||||
serialnum,
|
||||
timeutmult,
|
||||
rpi,
|
||||
transport,
|
||||
slavepath,
|
||||
pathlength
|
||||
)
|
||||
|
||||
if bool(connection) == False:
|
||||
raise TuxEIPException("Could not connect to CPU")
|
||||
|
||||
return connection
|
||||
|
||||
def ReadLgxData(self, sess_, conn_, var_, num_):
|
||||
self.__tuxeip._ReadLgxData.restype = POINTER(Eip_PLC_Read)
|
||||
readdata = self.__tuxeip._ReadLgxData(sess_, conn_, var_, num_)
|
||||
|
||||
if bool(readdata) == False:
|
||||
raise TuxEIPException("Read data failed")
|
||||
|
||||
return readdata
|
||||
|
||||
def WriteLGXData(self, sess_, conn_, address_, datatype_, data_, num_ ):
|
||||
if datatype_ == LGX_INT or datatype_ == LGX_BOOL or datatype_ == LGX_DINT or datatype_ == LGX_SINT:
|
||||
data = c_int(data_)
|
||||
elif datatype_ == LGX_REAL:
|
||||
data = c_float(data_)
|
||||
else:
|
||||
raise TuxEIPException("Write data failed")
|
||||
|
||||
data = self.__tuxeip._WriteLgxData(sess_, conn_, address_, datatype_, byref(data), num_)
|
||||
|
||||
return data
|
||||
|
||||
def ReadLGXDataAsFloat(self, sess_, conn_, var_, num_):
|
||||
data = self.ReadLgxData(sess_, conn_, var_, num_)
|
||||
d = self.GetLGXValueAsFloat(data)
|
||||
self.FreePLCRead(data)
|
||||
return d
|
||||
|
||||
def ReadLGXDataAsInteger(self, sess_, conn_, var_, num_):
|
||||
data = self.ReadLgxData(sess_, conn_, var_, num_)
|
||||
d = self.GetLGXValueAsInteger(data)
|
||||
self.FreePLCRead(data)
|
||||
return d
|
||||
|
||||
def ReadPLCDataAsFloat(self, sess_, conn_, dhp_, routepath_, routesize_, plctype_, tns_, address_, number_):
|
||||
data = self.ReadPLCData(sess_, conn_, dhp_, routepath_, routesize_, plctype_, tns_, address_, number_)
|
||||
d = self.PCCC_GetValueAsFloat(data)
|
||||
self.FreePLCRead(data)
|
||||
return d
|
||||
|
||||
def ReadPLCDataAsInteger(self, sess_, conn_, dhp_, routepath_, routesize_, plctype_, tns_, address_, number_):
|
||||
data = self.ReadPLCData(sess_, conn_, dhp_, routepath_, routesize_, plctype_, tns_, address_, number_)
|
||||
d = self.PCCC_GetValueAsInteger(data)
|
||||
self.FreePLCRead(data)
|
||||
return d
|
||||
|
||||
def ReadPLCData(self, sess_, conn_, dhp_, routepath_, routesize_, plctype_, tns_, address_, number_):
|
||||
self.__tuxeip._ReadPLCData.restype = POINTER(Eip_PLC_Read)
|
||||
readdata = self.__tuxeip._ReadPLCData(sess_, conn_, dhp_, routepath_, routesize_, plctype_,
|
||||
tns_, address_, number_)
|
||||
|
||||
if bool(readdata) == False:
|
||||
raise TuxEIPException("Read data failed")
|
||||
|
||||
return readdata
|
||||
|
||||
def GetLGXValueAsFloat(self, readdata_):
|
||||
if bool(readdata_) == False:
|
||||
return None
|
||||
|
||||
self.__tuxeip._GetLGXValueAsFloat.restype = c_float
|
||||
values = []
|
||||
for i in range(0, readdata_.contents.Varcount):
|
||||
v = self.__tuxeip._GetLGXValueAsFloat(readdata_, i)
|
||||
values.append(v)
|
||||
|
||||
return values
|
||||
|
||||
def GetLGXValueAsInteger(self, readdata_):
|
||||
if bool(readdata_) == False:
|
||||
return None
|
||||
|
||||
self.__tuxeip._GetLGXValueAsInteger.restype = c_int
|
||||
values = []
|
||||
for i in range(0, readdata_.contents.Varcount):
|
||||
v = self.__tuxeip._GetLGXValueAsInteger(readdata_, i)
|
||||
values.append(v)
|
||||
|
||||
return values
|
||||
|
||||
def PCCC_GetValueAsFloat(self, readdata_):
|
||||
if bool(readdata_) == False:
|
||||
return None
|
||||
|
||||
self.__tuxeip._PCCC_GetValueAsFloat.restype = c_float
|
||||
values = []
|
||||
for i in range(0, readdata_.contents.Varcount):
|
||||
v = self.__tuxeip._PCCC_GetValueAsFloat(readdata_, i)
|
||||
values.append(v)
|
||||
|
||||
return values
|
||||
|
||||
def PCCC_GetValueAsInteger(self, readdata_):
|
||||
if bool(readdata_) == False:
|
||||
return None
|
||||
|
||||
self.__tuxeip._PCCC_GetValueAsInteger.restype = c_int
|
||||
values = []
|
||||
for i in range(0, readdata_.contents.Varcount):
|
||||
v = self.__tuxeip._PCCC_GetValueAsInteger(readdata_, i)
|
||||
values.append(v)
|
||||
|
||||
return values
|
||||
|
||||
def WritePLCData(self, sess_, conn_, dhp_, routepath_, routesize_, plctype_, tns_, address_, datatype_, data_, number_):
|
||||
|
||||
if datatype_ == PLC_INTEGER:
|
||||
data = c_int(data_)
|
||||
elif datatype_ == PLC_FLOATING:
|
||||
data = c_float(data_)
|
||||
else:
|
||||
raise TuxEIPException("Variable type not supported" + str(datatype_))
|
||||
|
||||
result = self.__tuxeip._WritePLCData(sess_, conn_, dhp_, routepath_, routesize_, plctype_,
|
||||
tns_, address_, datatype_, byref(data), number_)
|
||||
|
||||
return result
|
||||
|
||||
def Forward_Close(self, conn_):
|
||||
self.__tuxeip._Forward_Close(conn_)
|
||||
|
||||
def UnRegisterSession(self, sess_):
|
||||
self.__tuxeip._UnRegisterSession(sess_)
|
||||
|
||||
def CloseSession(self, sess_):
|
||||
self.__tuxeip.CloseSession(sess_)
|
||||
|
||||
def FreePLCRead(self, data_):
|
||||
self.__tuxeip._FreePLCRead(data_)
|
||||
BIN
python/tuxeip.pyc
Normal file
BIN
python/tuxeip.pyc
Normal file
Binary file not shown.
78
www/app.js
Normal file
78
www/app.js
Normal file
@@ -0,0 +1,78 @@
|
||||
var express = require('express'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
logger = require('morgan'),
|
||||
methodOverride = require('method-override'),
|
||||
bodyParser = require('body-parser'),
|
||||
errorHandler = require('errorhandler');
|
||||
var app = express();
|
||||
|
||||
/**
|
||||
* Configuration
|
||||
*/
|
||||
var mysql = require('mysql');
|
||||
var db_config = {
|
||||
host: 'localhost',
|
||||
user: 'website',
|
||||
password: 'henrypump'
|
||||
};
|
||||
var handleDisconnect = function () {
|
||||
console.log("Handling db disconnect gracefully");
|
||||
app.locals.db = mysql.createConnection(db_config);
|
||||
app.locals.db.connect(function (err) {
|
||||
if (err) {
|
||||
console.log('error when connecting to db:', err);
|
||||
setTimeout(handleDisconnect, 2000);
|
||||
}
|
||||
});
|
||||
app.locals.db.on('error', function (err) {
|
||||
console.log('db error', err);
|
||||
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
|
||||
handleDisconnect();
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
};
|
||||
handleDisconnect();
|
||||
|
||||
app.set('port', process.env.PORT || 80);
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
app.engine('.html', require('ejs').renderFile);
|
||||
app.set('view engine', 'html');
|
||||
//app.use(favicon(__dirname + '/public/img/favicon.ico'));
|
||||
app.use(logger('dev'));
|
||||
app.use(methodOverride());
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({extended: true}));
|
||||
|
||||
//app.use(express["static"](path.join(__dirname, 'public')));
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
/**
|
||||
* Routes
|
||||
*/
|
||||
var fns = require('./functions.js');
|
||||
var angular = function(req, res) {
|
||||
res.render('angularIndex');
|
||||
};
|
||||
|
||||
app.get('/json/add/:tagName/:units', fns.addTag); // Adds a tag to the scan list
|
||||
app.get('/json/remove/:tag', fns.removeTag); // Removes a tag from the scan list
|
||||
app.get('/json/val/:tag', fns.latestTagValue); // Gets the latest value of a single tag
|
||||
app.get('/json/series/:tag/:hours', fns.seriesTagValues); // Gets all the values of a tag for the last X hours
|
||||
app.get('/json/tags', fns.allTags); // Lists all tags in the scan list
|
||||
app.get('/json/all', fns.allValues); // Gets the latest values of all tags in the scan list
|
||||
|
||||
app.get('*', angular);
|
||||
|
||||
/**
|
||||
* Start Server
|
||||
*/
|
||||
connectionsArray = [];
|
||||
s_port = 3000;
|
||||
var server = app.listen(s_port, function () {
|
||||
var host = server.address().address;
|
||||
var port = server.address().port;
|
||||
console.log('POConsole listening at http://%s:%s', host, port);
|
||||
});
|
||||
15
www/dbcreate.sql
Normal file
15
www/dbcreate.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE DATABASE SolarData;
|
||||
CREATE TABLE `SolarData`.`tags` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`tagName` VARCHAR(128) NULL,
|
||||
`dateAdded` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`units` VARCHAR(16) NULL,
|
||||
`deleted` INT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`));
|
||||
|
||||
CREATE TABLE `SolarData`.`values` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`tagID` INT NULL,
|
||||
`val` FLOAT NULL,
|
||||
`dateAdded` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`));
|
||||
68
www/functions.js
Normal file
68
www/functions.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// app.get('/json/add/:tag', fns.addTag); // Adds a tag to the scan list
|
||||
// app.get('/json/remove/:tag', fns.removeTag); // Removes a tag from the scan list
|
||||
// app.get('/json/val/:tag', fns.latestTagValue); // Gets the latest value of a single tag
|
||||
// app.get('/json/series/:tag/:hours', fns.seriesTagValues); // Gets all the values of a tag for the last X hours
|
||||
// app.get('/json/tags', fns.allTags); // Lists all tags in the scan list
|
||||
// app.get('/json/all', fns.allValues); // Gets the latest values of all tags in the scan list
|
||||
|
||||
|
||||
var getScanList = function(sl){
|
||||
var query = "SELECT * FROM SolarData.tags WHERE deleted = 0;";
|
||||
|
||||
};
|
||||
|
||||
exports.addTag = function(req, res){
|
||||
var vals = {
|
||||
tagName: req.params.tagName,
|
||||
units: req.params.units,
|
||||
};
|
||||
var query = "INSERT INTO SolarData.tags SET ?";
|
||||
req.app.locals.db.query(query, vals, function(err, rows, fields) {
|
||||
if (err) {
|
||||
res.json({status:"error", message:err});
|
||||
} else {
|
||||
res.json({status:"success"});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.removeTag = function(req, res){
|
||||
var query = "UPDATE SolarData.tags SET deleted = 1 WHERE id = " + parseInt(req.params.tag) + ";";
|
||||
req.app.locals.db.query(query, function(err, rows, fields) {
|
||||
if (err) {
|
||||
res.json({status:"error", message:err});
|
||||
} else {
|
||||
res.json({status:"success"});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.latestTagValue = function(req, res){
|
||||
var query = "SELECT * FROM SolarData.values WHERE id = (SELECT MAX(id) FROM SolarData.values WHERE tagID = (SELECT id FROM SolarData.tags WHERE tagName = '" + req.params.tag + "'));";
|
||||
req.app.locals.db.query(query, function(err, rows, fields) {
|
||||
if (err) {
|
||||
res.json({status:"error", message:err});
|
||||
} else {
|
||||
res.json({tag_val:rows[0]});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.seriesTagValues = function(req, res){
|
||||
res.json("not implemented");
|
||||
};
|
||||
|
||||
exports.allTags = function(req, res){
|
||||
var query = "SELECT * FROM SolarData.tags WHERE deleted = 0;";
|
||||
req.app.locals.db.query(query, function(err, rows, fields) {
|
||||
if (err) {
|
||||
res.json({status:"error", message:err});
|
||||
} else {
|
||||
res.json({tags:rows});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.allValues = function(req, res){
|
||||
res.json("not implemented");
|
||||
};
|
||||
25
www/package.json
Normal file
25
www/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "WaterWell DataLogger",
|
||||
"version": "1.0.0",
|
||||
"description": "Interface to Henry Pump Water Well Solar Panel",
|
||||
"main": "app.js",
|
||||
"dependencies": {
|
||||
"body-parser": "*",
|
||||
"ejs": "*",
|
||||
"errorhandler": "*",
|
||||
"express": "*",
|
||||
"method-override": "*",
|
||||
"morgan": "*",
|
||||
"mysql": "*",
|
||||
"serve-favicon": "*",
|
||||
"ya-csv": "*",
|
||||
"is-running":"*",
|
||||
"async":"*"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Patrick McDonagh",
|
||||
"license": "ISC"
|
||||
}
|
||||
66
www/views/angularIndex.html
Normal file
66
www/views/angularIndex.html
Normal file
@@ -0,0 +1,66 @@
|
||||
<html ng-app="wellSite" ng-controller="mainCtrl">
|
||||
|
||||
<head>
|
||||
<title>POConsole: {{ Page.title() }}</title>
|
||||
<meta http-equiv="content-type" context="text/html"; charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel='stylesheet' href='/css/bootstrap.css'>
|
||||
<link rel='stylesheet' href='/css/animate.css'>
|
||||
|
||||
<script src='/js/angular.min.js'></script>
|
||||
<script src='/js/angular-route.min.js'></script>
|
||||
<script src='/js/angular-animate.min.js'></script>
|
||||
<script src="/js/ui-bootstrap-0.12.0.min.js"></script>
|
||||
<script src="/js/ui-bootstrap-tpls-0.12.0.js"></script>
|
||||
<!-- <script src='/js/ng-socket-io.min.js'></script> -->
|
||||
<script src='/js/raphael-2.1.4.min.js'></script>
|
||||
<script src='/js/justgage-1.1.0.min.js'></script>
|
||||
<script src='/js/ng-justgage.js'></script>
|
||||
<script src="/js/d3.js"></script>
|
||||
<script src="/js/line-chart.min.js"></script>
|
||||
<!-- <script type='text/javascript' src='/socket.io/socket.io.js'></script> -->
|
||||
|
||||
<script src='/js/jquery-1.11.1.min.js'></script>
|
||||
<script src='/js/bootstrap.js'></script>
|
||||
|
||||
<script src="/js/router.js"></script>
|
||||
<script src="/js/controllers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" rel="home" href="/" title="Henry Pump">
|
||||
<img style="max-width:100px; "src="/img/logo.png">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-class="{active: Page.page() == 'dashboard'}"><a href="/#/">Dashboard</a></li>
|
||||
<li ng-class="{active: Page.page() == 'fileList'}"><a href="/#/files">Files</a></li>
|
||||
<li ng-class="{active: Page.page() == 'gaugeOff'}"><a href="/#/gaugeOff">Gauge Off</a></li>
|
||||
<li ng-class="{active: Page.page() == 'wellTest'}"><a href="/#/wellTest">Well Test</a></li>
|
||||
<li ng-class="{active: Page.page() == 'fluidshot'}"><a href="/#/fluid_shot">Fluid Shots</a></li>
|
||||
<li ng-class="{active: Page.page() == 'events'}"><a href="/#/events">Event List</a></li>
|
||||
<li ng-class="{active: Page.page() == 'notes'}"><a href="/#/notes">Notes</a></li>
|
||||
<!-- <li ng-class="{active: Page.page() == 'tags'}"><a href="/#/tags">Tags</a></li> -->
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li ng-class="{active: Page.page() == 'setup'}"><a href="/#/setup">Setup</a></li>
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
<div ng-view style="margin-top:40px;"></div>
|
||||
</body>
|
||||
Reference in New Issue
Block a user