Initial Commit
This commit is contained in:
211
alarmLogger.py
Normal file
211
alarmLogger.py
Normal file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
from datetime import datetime
|
||||
from random import randint
|
||||
from time import sleep
|
||||
import sys
|
||||
|
||||
# MYSQL Config
|
||||
import MySQLdb
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1", user="website", passwd="henrypump", db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
|
||||
sys.path.append("../")
|
||||
|
||||
|
||||
path_to_CSV = "/mnt/usb/"
|
||||
|
||||
# TUXEIP Connection to PLC
|
||||
# TUXEIP Connection to PLC
|
||||
from tuxeip import TuxEIP, LGX, LGX_REAL
|
||||
|
||||
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')
|
||||
|
||||
|
||||
|
||||
safetySetup = [["Safety_Casing_Pressure", "Casing Pressure"],
|
||||
["Safety_Flow_Line_Pressure", "Flow Line Pressure"],
|
||||
["Safety_Flowmeter", "Flowmeter"],
|
||||
["Safety_Fluid_Load", "Fluid Load"],
|
||||
["Safety_Inclinometer", "Inclinometer"],
|
||||
["Safety_Load_HiHi", "Load HiHi"],
|
||||
["Safety_Load_Hi", "Load Hi"],
|
||||
["Safety_Load_Lo", "Load Lo"],
|
||||
["Safety_Load_LoLo", "Load LoLo"],
|
||||
["Safety_Speed", "Speed"],
|
||||
["Safety_Tubing_Pressure", "Tubing Pressure"]
|
||||
]
|
||||
|
||||
condition = {
|
||||
20: "Low",
|
||||
21: "High",
|
||||
24: "LoLo",
|
||||
25: "HiHi",
|
||||
32: "Input Failure",
|
||||
34: "Configuration Error",
|
||||
16: "Failure to Stop",
|
||||
17: "Failure to Start",
|
||||
18: "Drive Fault"
|
||||
}
|
||||
|
||||
bitsSetup = [
|
||||
["Pump.Auto_Stop", "Pump Off (Auto Mode)", "Unit Stop"],
|
||||
["Pump.POC_Stop", "Pump Off (POC Mode)", "Unit Stop"],
|
||||
["Pump.Timed_Stop", "Pump Off (Timer Mode)", "Unit Stop"],
|
||||
["Pump.Stop", "User Initiated Stop", "Unit Stop"],
|
||||
["PeakEnergy.Stop", "Peak Energy Stop", "Unit Stop"],
|
||||
["Pump.Start", "User Initiated Start", "Unit Start"],
|
||||
["Pump.POC_Restart", "Restart (POC Mode)", "Unit Start"],
|
||||
["Pump.Timed_Restart", "Restart (Timer Mode)", "Unit Start"],
|
||||
["Pump.Auto_Restart", "Restart (Auto Mode)", "Unit Start"],
|
||||
["PeakEnergy.Restart", "Peak Energy Restart", "Unit Start"],
|
||||
["Pump.Jog", "Unit Jogged", "Unit Jog"],
|
||||
]
|
||||
|
||||
safetyList = []
|
||||
bitList = []
|
||||
|
||||
|
||||
class SafetyTag:
|
||||
"""Safety structure"""
|
||||
|
||||
def __init__(self, tag, name):
|
||||
self.name = name
|
||||
self.tag = tag
|
||||
self.alarm = False
|
||||
self.warning = False
|
||||
self.condition = ""
|
||||
self.type = ""
|
||||
self.value = 0.0
|
||||
self.stored = False
|
||||
|
||||
def writeToDB(self):
|
||||
global tux
|
||||
global sess
|
||||
global conn
|
||||
global condition
|
||||
stroke_num = int(tux.ReadLGXDataAsInteger(sess, conn, "Stroke_Count_Today", 1)[0])
|
||||
db = MySQLdb.connect(host="127.0.0.1", user="website", passwd="henrypump", db="WellData")
|
||||
cur = db.cursor()
|
||||
event_query = "INSERT INTO WellData.Event_List (device_name, type, cond, value, datetime, tag, stroke_number) VALUES ('{0}', '{1}', '{2}', {3}, '{4}', '{5}', {6});".format(
|
||||
self.name, self.type, self.condition, self.value, datetime.now(), self.name, stroke_num)
|
||||
print event_query
|
||||
store_event = cur.execute(event_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
self.stored = True
|
||||
|
||||
def ReadStatus(self):
|
||||
global tux
|
||||
global sess
|
||||
global conn
|
||||
global condition
|
||||
try:
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, self.tag + ".Alarm", 1)
|
||||
w = tux.ReadLGXDataAsInteger(sess, conn, self.tag + ".Warning", 1)
|
||||
aInt = int(a[0])
|
||||
wInt = int(w[0])
|
||||
if aInt == 1:
|
||||
self.alarm = True
|
||||
self.condition = condition[tux.ReadLGXDataAsInteger(sess, conn, self.tag + ".Alarm_Code", 1)]
|
||||
self.value = round(tux.ReadLGXDataAsInteger(sess, conn, self.tag + ".Alarm_Value", 1), 3)
|
||||
self.type = "Alarm"
|
||||
if (self.stored == False):
|
||||
self.writeToDB()
|
||||
elif wInt == 1:
|
||||
self.warning = True
|
||||
self.condition = condition[tux.ReadLGXDataAsInteger(sess, conn, self.tag + ".Alarm_Code", 1)]
|
||||
self.value = round(tux.ReadLGXDataAsInteger(sess, conn, self.tag + ".Alarm_Value", 1), 3)
|
||||
self.type = "Warning"
|
||||
if (self.stored == False):
|
||||
self.writeToDB()
|
||||
else:
|
||||
self.alarm = False
|
||||
self.warning = False
|
||||
self.condition = ""
|
||||
self.type = ""
|
||||
self.stored = False
|
||||
except:
|
||||
print "Unable to read " + self.tag
|
||||
|
||||
|
||||
class BitTag:
|
||||
"""Safety structure"""
|
||||
|
||||
def __init__(self, tag, name, condition):
|
||||
self.name = name
|
||||
self.tag = tag
|
||||
self.condition = condition
|
||||
self.type = "Info"
|
||||
self.value = 0.0
|
||||
self.stored = False
|
||||
|
||||
def writeToDB(self):
|
||||
global tux
|
||||
global sess
|
||||
global conn
|
||||
global condition
|
||||
stroke_num = int(tux.ReadLGXDataAsInteger(sess, conn, "Stroke_Count_Today", 1)[0])
|
||||
db = MySQLdb.connect(host="127.0.0.1", user="website", passwd="henrypump", db="WellData")
|
||||
cur = db.cursor()
|
||||
event_query = "INSERT INTO WellData.Event_List (device_name, type, cond, value, datetime, tag, stroke_number) VALUES ('{0}', '{1}', '{2}', {3}, '{4}', '{5}', {6});".format(
|
||||
self.name, self.type, self.condition, self.value, datetime.now(), self.name, stroke_num)
|
||||
print event_query
|
||||
store_event = cur.execute(event_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
self.stored = True
|
||||
|
||||
def ReadStatus(self):
|
||||
global tux
|
||||
global sess
|
||||
global conn
|
||||
global condition
|
||||
try:
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, self.tag, 1)
|
||||
aInt = int(a[0])
|
||||
# print self.tag + ": " + str(aInt)
|
||||
if aInt <> 0:
|
||||
if (self.stored == False):
|
||||
self.writeToDB()
|
||||
else:
|
||||
self.stored = False
|
||||
except:
|
||||
print "Unable to read " + self.tag
|
||||
|
||||
|
||||
for saf in safetySetup:
|
||||
safetyList.append(SafetyTag(saf[0], saf[1]))
|
||||
|
||||
for bit in bitsSetup:
|
||||
bitList.append(BitTag(bit[0], bit[1], bit[2]))
|
||||
|
||||
if (PLC_TYPE == "VFD"):
|
||||
safetyList.append(SafetyTag("Safety_Pump_PF755", "Drive"))
|
||||
if (PLC_TYPE == "E300"):
|
||||
safetyList.append(SafetyTag("Safety_E300", "Relay Overload"))
|
||||
|
||||
while True:
|
||||
for s in safetyList:
|
||||
s.ReadStatus()
|
||||
for b in bitList:
|
||||
b.ReadStatus()
|
||||
sleep(.50)
|
||||
143
alarmLogger_pycomm.py
Normal file
143
alarmLogger_pycomm.py
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from datetime import datetime
|
||||
from time import sleep
|
||||
import sys
|
||||
|
||||
# MYSQL Config
|
||||
import MySQLdb
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1", user="website", passwd="henrypump", db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
try:
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
except:
|
||||
print("PLC Address not set in database... using default of 192.168.1.10")
|
||||
PLC_IP_ADDRESS = "192.168.1.10"
|
||||
PLC_TYPE = "VFD"
|
||||
|
||||
#PYCOMM Connection to PLC
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
from pycomm.ab_comm.clx import CommError as ClxCommError
|
||||
from pycomm.ab_comm.clx import DataError as ClxDataError
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
|
||||
safetySetup = [{'tag':"Safety_Casing_Pressure", 'name':"Casing Pressure", "active":False},
|
||||
{'tag':"Safety_Flow_Line_Pressure", 'name':"Flow Line Pressure", "active":False},
|
||||
{'tag':"Safety_Flowmeter", 'name':"Flowmeter", "active":False},
|
||||
{'tag':"Safety_Fluid_Load", 'name':"Fluid Load", "active":False},
|
||||
{'tag':"Safety_Inclinometer", 'name':"Inclinometer", "active":False},
|
||||
{'tag':"Safety_Load_HiHi", 'name':"Load HiHi", "active":False},
|
||||
{'tag':"Safety_Load_Hi", 'name':"Load Hi", "active":False},
|
||||
{'tag':"Safety_Load_Lo", 'name':"Load Lo", "active":False},
|
||||
{'tag':"Safety_Load_LoLo", 'name':"Load LoLo", "active":False},
|
||||
{'tag':"Safety_Speed", 'name':"Speed", "active":False},
|
||||
{'tag':"Safety_Tubing_Pressure", 'name':"Tubing Pressure", "active":False}
|
||||
]
|
||||
|
||||
condition = {
|
||||
20: "Low",
|
||||
21: "High",
|
||||
24: "LoLo",
|
||||
25: "HiHi",
|
||||
32: "Input Failure",
|
||||
34: "Configuration Error",
|
||||
16: "Failure to Stop",
|
||||
17: "Failure to Start",
|
||||
18: "Drive Fault"
|
||||
}
|
||||
|
||||
bitsSetup = [
|
||||
{'tag':"Pump.Auto_Stop", 'name':"Pump Off (Auto Mode)", 'condition':"Unit Stop", 'active':False},
|
||||
{'tag':"Pump.POC_Stop", 'name':"Pump Off (POC Mode)", 'condition':"Unit Stop", 'active':False},
|
||||
{'tag':"Pump.Timed_Stop", 'name':"Pump Off (Timer Mode)", 'condition':"Unit Stop", 'active':False},
|
||||
{'tag':"Pump.Stop", 'name':"User Initiated Stop", 'condition':"Unit Stop", 'active':False},
|
||||
{'tag':"PeakEnergy.Stop", 'name':"Peak Energy Stop", 'condition':"Unit Stop", 'active':False},
|
||||
{'tag':"Pump.Start", 'name':"User Initiated Start", 'condition':"Unit Start", 'active':False},
|
||||
{'tag':"Pump.POC_Restart", 'name':"Restart (POC Mode)", 'condition':"Unit Start", 'active':False},
|
||||
{'tag':"Pump.Timed_Restart", 'name':"Restart (Timer Mode)", 'condition':"Unit Start", 'active':False},
|
||||
{'tag':"Pump.Auto_Restart", 'name':"Restart (Auto Mode)", 'condition':"Unit Start", 'active':False},
|
||||
{'tag':"PeakEnergy.Restart", 'name':"Peak Energy Restart", 'condition':"Unit Start", 'active':False},
|
||||
{'tag':"Pump.Jog", 'name':"Unit Jogged", 'condition':"Unit Jog", 'active':False},
|
||||
]
|
||||
|
||||
def write_alarm(name, type, condition, value, tag):
|
||||
"""writes the specified alarm to the MySQL database"""
|
||||
global c
|
||||
|
||||
stroke_num = int(c.read_tag(["Stroke_Count_Today"])[0][1])
|
||||
db = MySQLdb.connect(host="127.0.0.1", user="website", passwd="henrypump", db="WellData")
|
||||
cur = db.cursor()
|
||||
event_query = "INSERT INTO WellData.Event_List (device_name, type, cond, value, datetime, tag, stroke_number) VALUES ('{0}', '{1}', '{2}', {3}, '{4}', '{5}', {6});".format(
|
||||
name, type, condition, value, datetime.now(), tag, stroke_num)
|
||||
print event_query
|
||||
store_event = cur.execute(event_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
c.open(PLC_IP_ADDRESS)
|
||||
retry = False
|
||||
number_of_retry = 0
|
||||
while True:
|
||||
try:
|
||||
if retry:
|
||||
retry = False
|
||||
print "retrying"
|
||||
sleep(0.5)
|
||||
c.forward_close()
|
||||
if number_of_retry >= 5:
|
||||
c.close()
|
||||
c.open(PLC_IP_ADDRESS)
|
||||
number_of_retry = 0
|
||||
|
||||
for safety in safetySetup:
|
||||
try:
|
||||
alarm_sts = int(c.read_tag(["{0}.Alarm".format(safety['tag'])])[0][1])
|
||||
warning_sts = int(c.read_tag([safety['tag'] + ".Warning"])[0][1])
|
||||
print("Tag: {0}, Alarm: {1}, Warning: {2}".format(safety['tag'], alarm_sts, warning_sts))
|
||||
safety_type = ""
|
||||
if alarm_sts == 1:
|
||||
safety_type = "Alarm"
|
||||
if warning_sts == 1:
|
||||
safety_type = "Warning"
|
||||
if (alarm_sts == 1 or warning_sts == 1):
|
||||
safety_condition = condition[c.read_tag(["{0}.Alarm_Code".format(safety['tag'])])[0][1]]
|
||||
safety_value = round(c.read_tag(["{0}.Alarm_Value".format(safety['tag'])])[0][1], 3)
|
||||
if not safety['active']:
|
||||
write_alarm(safety['name'], safety_type, safety_condition, safety_value, safety['tag'])
|
||||
safety['active'] = True
|
||||
else:
|
||||
safety['active'] = False
|
||||
except Exception, e:
|
||||
print("[ERROR] Error reading safety {0}: {1}".format(safety['tag'], e))
|
||||
for bit in bitsSetup:
|
||||
try:
|
||||
bit_sts = int(c.read_tag([bit['tag']])[0][1])
|
||||
print("Tag: {0}, Status: {1}".format(bit['tag'], bit_sts))
|
||||
bit_type = "Info"
|
||||
if bit_sts == 1:
|
||||
bit_condition = bit['condition']
|
||||
bit_value = 0.0
|
||||
if not bit['active']:
|
||||
write_alarm(bit['name'], bit_type, bit_condition, bit_value, bit['tag'])
|
||||
bit['active'] = True
|
||||
else:
|
||||
bit['active'] = False
|
||||
except Exception, e:
|
||||
print("[ERROR] Error reading bit {0}: {1}".format(bit['tag'], e))
|
||||
|
||||
sleep(0.5)
|
||||
except ClxCommError as e:
|
||||
print(e)
|
||||
retry = True
|
||||
|
||||
except ClxDataError as e:
|
||||
print (e)
|
||||
c.close()
|
||||
138
backupPLC.py
Normal file
138
backupPLC.py
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
|
||||
#from prettytable import PrettyTable
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
from time import sleep
|
||||
import MySQLdb
|
||||
|
||||
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
|
||||
sys.path.append("../")
|
||||
|
||||
path_to_CSV = "/mnt/usb/"
|
||||
|
||||
#TUXEIP Connection to PLC
|
||||
from tuxeip import TuxEIP, LGX, LGX_REAL
|
||||
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')
|
||||
|
||||
now = datetime.now()
|
||||
nowDT = datetime.strftime(now,"%Y%m%d_%H%M%S")
|
||||
filename = path_to_CSV + "backup_"+nowDT+".csv"
|
||||
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
|
||||
taper_setup_params = [
|
||||
["Length","REAL"],
|
||||
["Diameter","REAL"],
|
||||
["Material","DINT"],
|
||||
["c","REAL"],
|
||||
["UseRodCount","BOOL"],
|
||||
["RodCount","DINT"]
|
||||
]
|
||||
|
||||
data = {}
|
||||
|
||||
tags_to_read = [['Casing_ID', 'REAL'],
|
||||
['UnitConfig.MotorNameplate.Volts', 'REAL'],
|
||||
['UnitConfig.MotorNameplate.Amps', 'REAL'],
|
||||
['UnitConfig.MotorNameplate.Hertz', 'REAL'],
|
||||
['UnitConfig.MotorNameplate.Poles', 'INT'],
|
||||
['UnitConfig.MotorNameplate.RPM', 'REAL'],
|
||||
['UnitConfig.MotorNameplate.ServiceFactor', 'REAL'],
|
||||
['UnitConfig.MotorNameplate.Horsepower', 'REAL'],
|
||||
['UnitConfig.Pump_Diameter', 'REAL'],
|
||||
['UnitConfig.Pump_Constant', 'REAL'],
|
||||
['UnitConfig.Anchor_Depth', 'REAL'],
|
||||
['UnitConfig.Total_Stroke_Length', 'REAL'],
|
||||
['UnitConfig.Motor_Sheave_Size', 'REAL'],
|
||||
['UnitConfig.Gearbox_Limit', 'REAL'],
|
||||
['UnitConfig.Gearbox_Ratio', 'REAL'],
|
||||
['UnitConfig.Gearbox_Sheave', 'REAL'],
|
||||
['UnitConfig.RPM_Maximum', 'REAL'],
|
||||
['UnitConfig.RPM_Minimum', 'REAL'],
|
||||
['UnitConfig.MotorCntrlMode', 'DINT'],
|
||||
['UnitConfig.MaxFreq', 'REAL'],
|
||||
['UnitConfig.Speed_Torque_Mode', 'DINT'],
|
||||
['UnitConfig.Rating_Gearbox', 'REAL'],
|
||||
['UnitConfig.Rating_Structural', 'REAL'],
|
||||
['UnitConfig.Well_Type', 'SINT'],
|
||||
['UnitConfig.Total_Vertical_Depth', 'REAL'],
|
||||
['UnitConfig.Total_Vertical_Depth_Input', 'REAL'],
|
||||
['UnitConfig.Tubing_Size_ID', 'REAL'],
|
||||
['UnitConfig.Tubing_Size_OD', 'REAL'],
|
||||
['UnitConfig.API_Oil', 'REAL'],
|
||||
['UnitConfig.SG_Water', 'REAL'],
|
||||
['UnitConfig.Percent_Water', 'REAL'],
|
||||
['Youngs_Modulus_Fiberglass', 'REAL'],
|
||||
['Youngs_Modulus_Steel', 'REAL'],
|
||||
]
|
||||
|
||||
|
||||
def ReadFromPLC(tag, tag_type):
|
||||
try:
|
||||
if (tag_type == "REAL"):
|
||||
a = tux.ReadLGXDataAsFloat(sess, conn, tag, 1)
|
||||
result = round(float(a[0]),3)
|
||||
#elif (tag_type == "INT" or tag_type == "DINT" or tag_type =="SINT"):
|
||||
elif tag_type[-3:] == "INT":
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
result = int(a[0])
|
||||
elif (tag_type == "BOOL"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
intermediate = int(a[0])
|
||||
if intermediate == 0:
|
||||
result = 0
|
||||
else:
|
||||
result = 1
|
||||
elif (tag_type =="STRING"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 82)
|
||||
word = ""
|
||||
for ch in range(len(a)):
|
||||
word = word + unichr(int(a[ch]))
|
||||
result = word
|
||||
else:
|
||||
result = "?"
|
||||
return result
|
||||
except:
|
||||
print "Unable to read " + tag
|
||||
return 911
|
||||
|
||||
|
||||
myfile = open(filename, 'wb')
|
||||
wr = csv.writer(myfile)
|
||||
for t in tags_to_read:
|
||||
tagVal = ReadFromPLC(t[0],t[1])
|
||||
if tagVal != 911:
|
||||
wr.writerow([t[0], tagVal, t[1]])
|
||||
wr.writerow(["TAPER", "CONFIG"])
|
||||
for i in range(0,11):
|
||||
for p in taper_setup_params:
|
||||
wr.writerow(["Taper.Taper[" + str(i) + "].Setup." + p[0], ReadFromPLC("Taper.Taper[" + str(i) + "].Setup." + p[0], p[1]), p[1]])
|
||||
myfile.close()
|
||||
print "Backed up PLC settings to", filename
|
||||
92
calibrateInclinometer.py
Normal file
92
calibrateInclinometer.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import readTag
|
||||
import writeTag
|
||||
from time import sleep
|
||||
import sys
|
||||
|
||||
def main():
|
||||
print ("Getting original limits...")
|
||||
read_min = readTag.main("Input_Inclinometer_AIN.Cfg_InpRawMin")
|
||||
if read_min['status']== 'success':
|
||||
prev_min = read_min['value']
|
||||
print ("Previous Min. Value: {0}".format(prev_min))
|
||||
else:
|
||||
print("Could not find previous min. value.")
|
||||
print("Error: {0}".format(read_min['message']))
|
||||
sys.exit(1)
|
||||
|
||||
read_max = readTag.main("Input_Inclinometer_AIN.Cfg_InpRawMax")
|
||||
if read_max['status']== 'success':
|
||||
prev_max = read_max['value']
|
||||
print ("Previous Max. Value: {0}".format(prev_max))
|
||||
else:
|
||||
print("Could not find previous max. value.")
|
||||
print("Error: {0}".format(read_max['message']))
|
||||
sys.exit(1)
|
||||
|
||||
write_calibrate = writeTag.main("Input_Inclinometer_Calibrate", 1)
|
||||
if write_calibrate['status']== 'success':
|
||||
sleep(2)
|
||||
unset_calibrate = writeTag.main("Input_Inclinometer_Calibrate", 0)
|
||||
if unset_calibrate['status']== 'success':
|
||||
check_calibrating = readTag.main("Inclinometer_Calibrating")
|
||||
if check_calibrating['status']== 'success' and check_calibrating['value']== 1:
|
||||
print ("Successfully Initiated Calibration...")
|
||||
i = 0
|
||||
while i < 30:
|
||||
x = 2
|
||||
print("[{0} s. Remaining] - Waiting for calibration".format(30 - i))
|
||||
sleep(x)
|
||||
i = i + x
|
||||
|
||||
check_calibrating_again = readTag.main("Inclinometer_Calibrating")
|
||||
if check_calibrating_again['status']== 'success' and check_calibrating_again['value']== 0:
|
||||
print ("Successfully Completed Calibration...")
|
||||
|
||||
read_min_again = readTag.main("Input_Inclinometer_AIN.Cfg_InpRawMin")
|
||||
if read_min_again['status']== 'success':
|
||||
new_min = read_min_again['value']
|
||||
print ("New Min. Value: {0}".format(new_min))
|
||||
else:
|
||||
print("Could not find new min. value.")
|
||||
print("Error: {0}".format(read_min_again['message']))
|
||||
sys.exit(1)
|
||||
|
||||
read_max_again = readTag.main("Input_Inclinometer_AIN.Cfg_InpRawMax")
|
||||
if read_max_again['status']== 'success':
|
||||
new_max = read_max_again['value']
|
||||
print ("New Max. Value: {0}".format(new_max))
|
||||
else:
|
||||
print("Could not find new max. value.")
|
||||
print("Error: {0}".format(read_max_again['message']))
|
||||
sys.exit(1)
|
||||
|
||||
print("Calibration process complete. Thanks for playing...")
|
||||
|
||||
else:
|
||||
if check_calibrating_again['message']:
|
||||
print("Error reading Inclinometer_Calibrating")
|
||||
print("Error: {0}".format(write_calibrate['message']))
|
||||
else:
|
||||
print("Calibration still running. Something went wrong.")
|
||||
sys.exit(1)
|
||||
|
||||
else:
|
||||
if write_calibrate['message']:
|
||||
print("Error reading Inclinometer_Calibrating")
|
||||
print("Error: {0}".format(write_calibrate['message']))
|
||||
else:
|
||||
print("Calibration not started. Is the pump running?")
|
||||
sys.exit(1)
|
||||
|
||||
else:
|
||||
print("Could not write 0 to Input_Inclinometer_Calibrate")
|
||||
print("Error: {0}".format(write_calibrate['message']))
|
||||
sys.exit(1)
|
||||
|
||||
else:
|
||||
print("Could not write 1 to Input_Inclinometer_Calibrate")
|
||||
print("Error: {0}".format(write_calibrate['message']))
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
376
dataLogger.py
Normal file
376
dataLogger.py
Normal file
@@ -0,0 +1,376 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
|
||||
#from prettytable import PrettyTable
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
import time
|
||||
import MySQLdb
|
||||
|
||||
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
|
||||
sys.path.append("../")
|
||||
|
||||
path_to_CSV = "/mnt/usb/"
|
||||
|
||||
#TUXEIP Connection to PLC
|
||||
from tuxeip import TuxEIP, LGX, LGX_REAL
|
||||
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')
|
||||
|
||||
if os.path.exists(path_to_CSV + "current.csv"):
|
||||
os.remove(path_to_CSV + "current.csv")
|
||||
|
||||
|
||||
|
||||
data = {}
|
||||
|
||||
tags_to_read = [['Card_Past[1].ID', 'INT', "Card_ID"],
|
||||
['Card_Past[1].Params.Num_Tapers', 'INT', 'Num_Tapers'],
|
||||
['Card_Past[1].Num_Points', 'INT', 'Num_Points'],
|
||||
['Card_Past[1].Card_Type', 'INT', 'Card_Type'],
|
||||
['Card_Past[1].Name.Data[0]','STRING', 'Well_Name'],
|
||||
['Card_Past[1].Params.Tubing_Head_Pressure','REAL', 'Tubing_Head_Pressure'],
|
||||
['Card_Past[1].Params.Fluid_Gradient','REAL', 'Fluid_Gradient'],
|
||||
['Card_Past[1].Params.Stuffing_Box_Friction','REAL', 'Stuffing_Box_Friction'],
|
||||
['Card_Past[1].Params.dt','REAL', 'dt'],
|
||||
['Card_Past[1].Downhole_Max_Load.Load','REAL', 'Downhole_Max_Load'],
|
||||
['Card_Past[1].Downhole_Min_Load.Load','REAL', 'Downhole_Min_Load'],
|
||||
['Card_Past[1].Downhole_Max_Position.Position','REAL', 'Downhole_Max_Position'],
|
||||
['Card_Past[1].Downhole_Min_Position.Position','REAL', 'Downhole_Min_Position'],
|
||||
['Card_Past[1].Downhole_GrossStroke','REAL', 'Downhole_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_AdjustedGrossStroke','REAL', 'Downhole_Adjusted_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_NetStroke','REAL', 'Downhole_Net_Stroke'],
|
||||
['Card_Past[1].Downhole_FluidLoad','REAL', 'Downhole_Fluid_Load'],
|
||||
['Card_Past[1].Surface_Max.Load','REAL', 'Surface_Max_Load'],
|
||||
['Card_Past[1].Surface_Min.Load','REAL', 'Surface_Min_Load'],
|
||||
['Card_Past[1].Surface_Max.Position','REAL', 'Surface_Max_Position'],
|
||||
['Card_Past[1].Surface_Min.Position','REAL', 'Surface_Min_Position'],
|
||||
['Card_Past[1].Tubing_Movement','REAL', 'Tubing_Movement'],
|
||||
['Card_Past[1].Surface_StrokeLength','REAL', 'Surface_Stroke_Length'],
|
||||
['Card_Past[1].Fillage_Percent','REAL', 'Fillage_Percent'],
|
||||
['Card_Past[1].Polished_Rod_HP','REAL', 'Polished_Rod_HP'],
|
||||
['Card_Past[1].Pump_HP','REAL', 'Pump_HP'],
|
||||
['Card_Past[1].SPM','REAL', 'SPM'],
|
||||
['Card_Past[1].Fluid_Above_Pump','REAL', 'Fluid_Above_Pump'],
|
||||
['Card_Past[1].Pump_Intake_Pressure','REAL', 'Pump_Intake_Pressure'],
|
||||
['Stroke_Production','REAL', 'Stroke_Production'],
|
||||
['DriveTorqueMode','BOOL', 'Drive_Torque_Mode'],
|
||||
['PF755_Drive:O.TrqRefAStpt','REAL', 'Torque_Reference'],
|
||||
['Pump_PF755.PSet_SpeedRef','REAL', 'Speed_Reference'],
|
||||
]
|
||||
|
||||
datetime_tags = [
|
||||
['Card_Past[1].End_Time.Year', 'INT', '_Year'],
|
||||
['Card_Past[1].End_Time.Month', 'INT', '_Month'],
|
||||
['Card_Past[1].End_Time.Day', 'INT', '_Day'],
|
||||
['Card_Past[1].End_Time.Hour', 'INT', '_Hour'],
|
||||
['Card_Past[1].End_Time.Min', 'INT', '_Minute'],
|
||||
['Card_Past[1].End_Time.Sec', 'INT', '_Second']
|
||||
]
|
||||
|
||||
|
||||
def ReadFromPLC(tag, tag_type):
|
||||
try:
|
||||
if (tag_type == "REAL"):
|
||||
a = tux.ReadLGXDataAsFloat(sess, conn, tag, 1)
|
||||
#print a
|
||||
result = float(a[0])
|
||||
#print tag, result
|
||||
elif (tag_type == "INT"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
#print a
|
||||
result = int(a[0])
|
||||
#print tag, result
|
||||
elif (tag_type == "BOOL"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
val = int(a[0])
|
||||
if val != 0:
|
||||
val = 1
|
||||
result = val
|
||||
elif (tag_type =="STRING"):
|
||||
#print "./read_"+tag_type+ " , " + tag
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 82)
|
||||
#print a
|
||||
#split_chars = a.split(",")
|
||||
#print split_chars
|
||||
word = ""
|
||||
for ch in range(len(a)):
|
||||
word = word + unichr(int(a[ch]))
|
||||
#print word
|
||||
result = word
|
||||
else:
|
||||
result = "?"
|
||||
return result
|
||||
except:
|
||||
print "Unable to read " + tag
|
||||
return 911
|
||||
|
||||
def readPoints():
|
||||
surface = []
|
||||
downhole = []
|
||||
for i in range(0, data['Num_Points']):
|
||||
sp = round(ReadFromPLC("Card_Past[1].Surface_Position[" + str(i) + "]", "REAL"),3)
|
||||
sl = round(ReadFromPLC("Card_Past[1].Surface_Load[" + str(i) + "]", "REAL"),3)
|
||||
surface.append([sp,sl])
|
||||
|
||||
dp = round(ReadFromPLC("Card_Past[1].Downhole_Position[" + str(i) + "]", "REAL"),3)
|
||||
dl = round(ReadFromPLC("Card_Past[1].Downhole_Load[" + str(i) + "]", "REAL"),3)
|
||||
downhole.append([dp, dl])
|
||||
|
||||
|
||||
def readSetpoints():
|
||||
modeMap = {
|
||||
0: "Error",
|
||||
1: "Auto",
|
||||
2: "POC",
|
||||
3: "Timer",
|
||||
4: "Manual",
|
||||
5: "DH PID"
|
||||
}
|
||||
|
||||
|
||||
with open('/mnt/usb/setpoints.csv', 'w') as setpoint_file:
|
||||
wr = csv.writer(setpoint_file)
|
||||
stroke_time = time.time()
|
||||
dt = datetime.fromtimestamp(stroke_time)
|
||||
wr.writerow(['localtime', dt])
|
||||
wr.writerow(['utctime', datetime.utcfromtimestamp(stroke_time)])
|
||||
wr.writerow(['Mode', ReadFromPLC("Pump.Mode", "INT")])
|
||||
wr.writerow(['Speed_Setpoint_SPM', ReadFromPLC("Pump.Speed_Setpoint_SPM", "REAL")])
|
||||
wr.writerow(['Speed_Max', ReadFromPLC("Pump.Speed_Max", "REAL")])
|
||||
wr.writerow(['Speed_Min', ReadFromPLC("Pump.Speed_Min", "REAL")])
|
||||
wr.writerow(['Auto-Speed_Startpoint_SPM', ReadFromPLC("Pump.Speed_Startpoint_SPM_Auto", "REAL")])
|
||||
wr.writerow(['Auto-Percentage_Ramp_Down', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Increment_Ramp_Down', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Up', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Down', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Min_Speed_Strokes', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Up', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-POC-Startup_Ignore_Cards', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-POC-Card_Quantity', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Up', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['POC-Percent_Pumpoff', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
|
||||
|
||||
cards_read = 1
|
||||
read_tapers = False
|
||||
already_gauged_off = False
|
||||
already_entered_well_test = False
|
||||
while True:
|
||||
now = datetime.now()
|
||||
with open('/mnt/usb/status.txt', 'w') as status_file:
|
||||
status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.strftime(now,"%Y%m%d_%H%M%S"), ReadFromPLC("Pump.Run_Status", "INT"),ReadFromPLC("Card_Past[1].ID", "INT"),ReadFromPLC("Card_Past[1].Fillage_Percent", "REAL"),ReadFromPLC("Card_Past[1].Fluid_Above_Pump", "REAL"),ReadFromPLC("Stroke_Production", "REAL")))
|
||||
#status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.now(), ReadFromPLC("Pump.Run_Status", "INT"),ReadFromPLC("Card_Past[1].ID", "INT"),ReadFromPLC("Card_Past[1].Fillage_Percent", "REAL"),ReadFromPLC("Card_Past[1].Fluid_Above_Pump", "REAL"),ReadFromPLC("Stroke_Production", "REAL")))
|
||||
|
||||
#############
|
||||
# CARD DATA #
|
||||
#############
|
||||
|
||||
EOS = ReadFromPLC("End_Of_Stroke", "INT")
|
||||
Already_Read = ReadFromPLC("Card_Past[1].Data_Read", "INT") > 0
|
||||
num_points = ReadFromPLC("Card_Past[1].Num_Points", "INT")
|
||||
|
||||
|
||||
if (EOS and not Already_Read and (EOS != 911)):
|
||||
filename = path_to_CSV + "current.csv"
|
||||
myfile = open(filename, 'wb')
|
||||
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
|
||||
stroke_time = time.time()
|
||||
dt = datetime.fromtimestamp(stroke_time)
|
||||
wr.writerow(['localtime', dt])
|
||||
wr.writerow(['utctime', datetime.utcfromtimestamp(stroke_time)])
|
||||
for t in tags_to_read:
|
||||
#print t
|
||||
data[t[2]] = ReadFromPLC(t[0], t[1])
|
||||
wr.writerow([t[2] ,data[t[2]]])
|
||||
wr.writerow(["s_pos", "s_load"])
|
||||
for i in range(1, num_points-1):
|
||||
wr.writerow([round(ReadFromPLC("Card_Past[1].Surface_Position[" + str(i) + "]", "REAL"),3), round(ReadFromPLC("Card_Past[1].Surface_Load[" + str(i) + "]", "REAL"),3)])
|
||||
wr.writerow(["d_pos", "d_load"])
|
||||
for i in range(1, num_points-1):
|
||||
wr.writerow([round(ReadFromPLC("Card_Past[1].Downhole_Position[" + str(i) + "]", "REAL"),3), round(ReadFromPLC("Card_Past[1].Downhole_Load[" + str(i) + "]", "REAL"),3)])
|
||||
myfile.close()
|
||||
|
||||
st = datetime.strftime(dt,"%Y%m%d_%H%M%S")
|
||||
date = datetime.strftime(dt,"%Y%m%d")
|
||||
|
||||
if (data["Card_Type"] == 0):
|
||||
data["Card_Type"] = "Normal"
|
||||
elif (data["Card_Type"]==1):
|
||||
data["Card_Type"] = "Shutdown"
|
||||
elif (data["Card_Type"]==2):
|
||||
data["Card_Type"] = "Alarm"
|
||||
elif (data["Card_Type"]==3):
|
||||
data["Card_Type"] = "Startup"
|
||||
else:
|
||||
data["Card_Type"] ="Unknown"
|
||||
|
||||
if not os.path.exists(path_to_CSV +"CSV/"+date):
|
||||
os.makedirs(path_to_CSV+"CSV/"+date)
|
||||
|
||||
fill_percent_file = str(data['Fillage_Percent']).replace(".","-")
|
||||
rename_file = path_to_CSV+"CSV/"+ date+"/"+st+"_"+str(data["Card_ID"])+"_"+data['Card_Type']+ "_"+fill_percent_file +".csv"
|
||||
os.rename(filename, rename_file)
|
||||
|
||||
tux.WriteLGXData(sess, conn, "Card_Past[1].Data_Read", LGX_REAL, 1, 1)
|
||||
print "CARD NUMBER " + str(cards_read) + " READ: "+str(data["Card_ID"])+ ", STORED AS "+ rename_file
|
||||
cards_read = cards_read + 1
|
||||
|
||||
|
||||
##############
|
||||
# TAPER DATA #
|
||||
##############
|
||||
|
||||
update_taper = ReadFromPLC("Write_Tapers", "INT")
|
||||
if (update_taper == 0):
|
||||
if read_tapers:
|
||||
read_tapers = False
|
||||
print "Update Tapers = False"
|
||||
|
||||
if (update_taper and (not read_tapers) and (update_taper != 911)):
|
||||
print "reading taper file"
|
||||
taper_count = 0;
|
||||
|
||||
tFilename = path_to_CSV + "CSV/TAPER/TAPER_" + datetime.strftime(now,"%Y%m%d_%H%M%S")+ '.CSV'
|
||||
tFile = open(tFilename, 'wb')
|
||||
twr = csv.writer(tFile, quoting=csv.QUOTE_ALL)
|
||||
for taps in range(1,10):
|
||||
taper_in_use_temp = ReadFromPLC('Taper.Taper[' + str(taps)+'].Calculated.InUse', "INT")
|
||||
if taper_in_use_temp:
|
||||
taper_count = taper_count + 1
|
||||
#print "reading Taper"+ str(taper_count)
|
||||
twr.writerow(["Taper",taper_count])
|
||||
twr.writerow(['Length',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Length', 'REAL')])
|
||||
twr.writerow(['Diameter',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Diameter', 'REAL')])
|
||||
tMaterial = ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Material', 'INT')
|
||||
if (tMaterial == 1):
|
||||
twr.writerow(['Material',"Steel"])
|
||||
elif (tMaterial == 2):
|
||||
twr.writerow(['Material',"Fiberglass"])
|
||||
twr.writerow(['Weight_Per_Foot', ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Weight', 'REAL')])
|
||||
twr.writerow(['Youngs_Modulus',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Youngs_Modulus', 'REAL')])
|
||||
twr.writerow(['Damping_Factor',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.c', 'REAL')])
|
||||
twr.writerow(['Area',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Area', 'REAL')])
|
||||
twr.writerow(['Rod_Depth',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Rod_Depth', 'REAL')])
|
||||
twr.writerow(['Pressure',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Pressure', 'REAL')])
|
||||
twr.writerow(['Buoyant_Force',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Buoyant_Force', 'REAL')])
|
||||
twr.writerow(['Rod_Weight',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Rod_Weight_Air', 'REAL')])
|
||||
twr.writerow(['Force',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Force', 'REAL')])
|
||||
twr.writerow(['Stretch',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Stretch', 'REAL')])
|
||||
twr.writerow(["",""])
|
||||
else:
|
||||
break
|
||||
twr.writerow(["UnitConfig",""])
|
||||
twr.writerow(['Pump_Diameter',ReadFromPLC('UnitConfig.Pump_Diameter', 'REAL')])
|
||||
tFile.close()
|
||||
read_tapers = True
|
||||
print "TAPER DATA READ: "+ tFilename
|
||||
|
||||
##################
|
||||
# GAUGE OFF DATA #
|
||||
##################
|
||||
gauge_off = ReadFromPLC("Gauge_Off_Command", "INT")
|
||||
if (gauge_off == 0):
|
||||
if already_gauged_off:
|
||||
already_gauged_off = False
|
||||
print "Already gauged off... Setting gauge_off to False"
|
||||
|
||||
if (gauge_off and (not already_gauged_off) and (gauge_off != 911)):
|
||||
print "Gauging off..."
|
||||
gYear = ReadFromPLC("GAUGEOFF_DateTime.Year", "INT")
|
||||
gMonth = ReadFromPLC("GAUGEOFF_DateTime.Month", "INT")
|
||||
gDay = ReadFromPLC("GAUGEOFF_DateTime.Day", "INT")
|
||||
gHour = ReadFromPLC("GAUGEOFF_DateTime.Hour", "INT")
|
||||
gMin = ReadFromPLC("GAUGEOFF_DateTime.Min", "INT")
|
||||
gSec = ReadFromPLC("GAUGEOFF_DateTime.Sec", "INT")
|
||||
gauge_date = datetime(year = gYear, month = gMonth,day = gDay,hour = gHour,minute = gMin,second = gSec)
|
||||
percent_run = round(ReadFromPLC("GAUGEOFF_Percent_Run", "REAL"),2)
|
||||
kWh = round(ReadFromPLC("GAUGEOFF_kWh", "REAL"),3)
|
||||
electricity_cost = round(ReadFromPLC("GAUGEOFF_Electricity_Cost", "REAL"),2)
|
||||
peak_load = round(ReadFromPLC("GAUGEOFF_Max_Load", "REAL"),3)
|
||||
min_load = round(ReadFromPLC("GAUGEOFF_Min_Load", "REAL"),3)
|
||||
average_SPM = round(ReadFromPLC("GAUGEOFF_Average_SPM", "REAL"),4)
|
||||
production_calculated = round(ReadFromPLC("GAUGEOFF_Production_Calculated", "REAL"),2)
|
||||
full_card_production = round(ReadFromPLC("GAUGEOFF_Full_Card_Production", "REAL"),2)
|
||||
polished_rod_HP = round(ReadFromPLC("GAUGEOFF_Polished_Rod_HP", "REAL"),3)
|
||||
lifting_cost = round(ReadFromPLC("GAUGEOFF_Lifting_Cost", "REAL"),4)
|
||||
fluid_above_pump = round(ReadFromPLC("GAUGEOFF_Fluid_Above_Pump", "REAL"),2)
|
||||
pump_intake_pressure = round(ReadFromPLC("GAUGEOFF_pump_intake_pressure", "REAL"),2)
|
||||
kWh_regen = round(ReadFromPLC("GAUGEOFF_kWh_regen", "REAL"),2)
|
||||
inflow_rate = round(ReadFromPLC("GAUGEOFF_Inflow_Rate", "REAL"),4)
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
print """INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate)
|
||||
storeHist = cur.execute("""INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate))
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_gauged_off = True
|
||||
print "Gauged off!"
|
||||
|
||||
|
||||
##################
|
||||
# WELL TEST DATA #
|
||||
##################
|
||||
|
||||
well_test_entered = ReadFromPLC("Well_Test.Test_Submit", "INT")
|
||||
if (well_test_entered == 0):
|
||||
if already_entered_well_test:
|
||||
already_entered_well_test = False
|
||||
print "Already entered well Test... Setting well_test_entered to False"
|
||||
if (well_test_entered and (not already_entered_well_test) and well_test_entered != 911):
|
||||
print "Well Test Entered"
|
||||
|
||||
tYear = ReadFromPLC("Well_Test.DateTime_Complete.Year", "INT")
|
||||
tMonth = ReadFromPLC("Well_Test.DateTime_Complete.Month", "INT")
|
||||
tDay = ReadFromPLC("Well_Test.DateTime_Complete.Day", "INT")
|
||||
tHour = ReadFromPLC("Well_Test.DateTime_Complete.Hour", "INT")
|
||||
tMin = ReadFromPLC("Well_Test.DateTime_Complete.Min", "INT")
|
||||
tSec = ReadFromPLC("Well_Test.DateTime_Complete.Sec", "INT")
|
||||
test_date = datetime(year = tYear, month = tMonth,day = tDay,hour = tHour,minute = tMin,second = tSec)
|
||||
test_duration = round(ReadFromPLC("Well_Test.Test_Duration", "REAL"),3)
|
||||
v_water = round(ReadFromPLC("Well_Test.Volume_Water", "REAL"),3)
|
||||
v_oil = round(ReadFromPLC("Well_Test.Volume_Oil", "REAL"),3)
|
||||
v_gas = round(ReadFromPLC("Well_Test.Volume_Gas", "REAL"),3)
|
||||
p_v_water = round(ReadFromPLC("Well_Test.Projected_Volume_Water", "REAL"),3)
|
||||
p_v_oil = round(ReadFromPLC("Well_Test.Projected_Volume_Oil", "REAL"),3)
|
||||
k_factor = round(ReadFromPLC("Well_Test.k_Factor", "REAL"),3)
|
||||
api_oil = round(ReadFromPLC("Well_Test.API_Oil", "REAL"),3)
|
||||
sg_water = round(ReadFromPLC("Well_Test.SG_Water", "REAL"),3)
|
||||
|
||||
db = MySQLdb.connect(host="localhost",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
test_query = "INSERT INTO WellData.Well_Test (test_date, test_volume_oil, test_volume_water, test_volume_gas, k_factor, projected_volume_oil, projected_volume_water, api_gravity_oil, sg_water, test_hours) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}');".format(test_date, v_oil, v_water, v_gas, k_factor, p_v_oil, p_v_water, api_oil, sg_water, test_duration)
|
||||
print test_query
|
||||
storeTest = cur.execute(test_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_entered_well_test = True
|
||||
print "Well Test Stored!"
|
||||
|
||||
time.sleep(.20)
|
||||
395
dataLoggerMySQL.py
Normal file
395
dataLoggerMySQL.py
Normal file
@@ -0,0 +1,395 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
|
||||
#from prettytable import PrettyTable
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
import time
|
||||
import MySQLdb
|
||||
|
||||
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
|
||||
sys.path.append("../")
|
||||
|
||||
path_to_CSV = "/mnt/usb/"
|
||||
|
||||
#TUXEIP Connection to PLC
|
||||
from tuxeip import TuxEIP, LGX, LGX_REAL
|
||||
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')
|
||||
|
||||
if os.path.exists(path_to_CSV + "current.csv"):
|
||||
os.remove(path_to_CSV + "current.csv")
|
||||
|
||||
|
||||
|
||||
data = {}
|
||||
|
||||
tags_to_read = [['Card_Past[1].ID', 'INT', "Card_ID"],
|
||||
['Card_Past[1].Params.Num_Tapers', 'INT', 'Num_Tapers'],
|
||||
['Card_Past[1].Num_Points', 'INT', 'Num_Points'],
|
||||
['Card_Past[1].Card_Type', 'INT', 'Card_Type'],
|
||||
['Card_Past[1].Name.Data[0]','STRING', 'Well_Name'],
|
||||
['Card_Past[1].Params.Tubing_Head_Pressure','REAL', 'Tubing_Head_Pressure'],
|
||||
['Card_Past[1].Params.Fluid_Gradient','REAL', 'Fluid_Gradient'],
|
||||
['Card_Past[1].Params.Stuffing_Box_Friction','REAL', 'Stuffing_Box_Friction'],
|
||||
['Card_Past[1].Params.dt','REAL', 'dt'],
|
||||
['Card_Past[1].Downhole_Max_Load.Load','REAL', 'Downhole_Max_Load'],
|
||||
['Card_Past[1].Downhole_Min_Load.Load','REAL', 'Downhole_Min_Load'],
|
||||
['Card_Past[1].Downhole_Max_Position.Position','REAL', 'Downhole_Max_Position'],
|
||||
['Card_Past[1].Downhole_Min_Position.Position','REAL', 'Downhole_Min_Position'],
|
||||
['Card_Past[1].Downhole_GrossStroke','REAL', 'Downhole_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_AdjustedGrossStroke','REAL', 'Downhole_Adjusted_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_NetStroke','REAL', 'Downhole_Net_Stroke'],
|
||||
['Card_Past[1].Downhole_FluidLoad','REAL', 'Downhole_Fluid_Load'],
|
||||
['Card_Past[1].Surface_Max.Load','REAL', 'Surface_Max_Load'],
|
||||
['Card_Past[1].Surface_Min.Load','REAL', 'Surface_Min_Load'],
|
||||
['Card_Past[1].Surface_Max.Position','REAL', 'Surface_Max_Position'],
|
||||
['Card_Past[1].Surface_Min.Position','REAL', 'Surface_Min_Position'],
|
||||
['Card_Past[1].Tubing_Movement','REAL', 'Tubing_Movement'],
|
||||
['Card_Past[1].Surface_StrokeLength','REAL', 'Surface_Stroke_Length'],
|
||||
['Card_Past[1].Fillage_Percent','REAL', 'Fillage_Percent'],
|
||||
['Card_Past[1].Polished_Rod_HP','REAL', 'Polished_Rod_HP'],
|
||||
['Card_Past[1].Pump_HP','REAL', 'Pump_HP'],
|
||||
['Card_Past[1].SPM','REAL', 'SPM'],
|
||||
['Card_Past[1].Fluid_Above_Pump','REAL', 'Fluid_Level'],
|
||||
['Card_Past[1].Pump_Intake_Pressure','REAL', 'Pump_Intake_Pressure'],
|
||||
['Stroke_Production','REAL', 'Stroke_Production'],
|
||||
['DriveTorqueMode','BOOL', 'Drive_Torque_Mode'],
|
||||
]
|
||||
mode_tags = {"torque":['PF755_Drive:O.TrqRefAStpt','REAL', 'Torque_Reference'],
|
||||
"speed":['Pump_PF755.PSet_SpeedRef','REAL', 'Speed_Reference']}
|
||||
datetime_tags = [
|
||||
['Card_Past[1].End_Time.Year', 'INT', '_Year'],
|
||||
['Card_Past[1].End_Time.Month', 'INT', '_Month'],
|
||||
['Card_Past[1].End_Time.Day', 'INT', '_Day'],
|
||||
['Card_Past[1].End_Time.Hour', 'INT', '_Hour'],
|
||||
['Card_Past[1].End_Time.Min', 'INT', '_Minute'],
|
||||
['Card_Past[1].End_Time.Sec', 'INT', '_Second']
|
||||
]
|
||||
|
||||
|
||||
def ReadFromPLC(tag, tag_type):
|
||||
try:
|
||||
if (tag_type == "REAL"):
|
||||
a = tux.ReadLGXDataAsFloat(sess, conn, tag, 1)
|
||||
#print a
|
||||
result = float(a[0])
|
||||
#print tag, result
|
||||
elif (tag_type == "INT"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
#print a
|
||||
result = int(a[0])
|
||||
#print tag, result
|
||||
elif (tag_type == "BOOL"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
val = int(a[0])
|
||||
if val != 0:
|
||||
val = 1
|
||||
result = val
|
||||
elif (tag_type =="STRING"):
|
||||
#print "./read_"+tag_type+ " , " + tag
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 82)
|
||||
#print a
|
||||
#split_chars = a.split(",")
|
||||
#print split_chars
|
||||
word = ""
|
||||
for ch in range(len(a)):
|
||||
word = word + unichr(int(a[ch]))
|
||||
#print word
|
||||
result = word
|
||||
else:
|
||||
result = "?"
|
||||
return result
|
||||
except:
|
||||
print "Unable to read " + tag
|
||||
return 911
|
||||
|
||||
def readPoints():
|
||||
surface = []
|
||||
downhole = []
|
||||
for i in range(0, data['Num_Points']):
|
||||
sp = round(ReadFromPLC("Card_Past[1].Surface_Position[" + str(i) + "]", "REAL"),3)
|
||||
sl = round(ReadFromPLC("Card_Past[1].Surface_Load[" + str(i) + "]", "REAL"),3)
|
||||
surface.append([sp,sl])
|
||||
|
||||
dp = round(ReadFromPLC("Card_Past[1].Downhole_Position[" + str(i) + "]", "REAL"),3)
|
||||
dl = round(ReadFromPLC("Card_Past[1].Downhole_Load[" + str(i) + "]", "REAL"),3)
|
||||
downhole.append([dp, dl])
|
||||
|
||||
|
||||
def readSetpoints():
|
||||
modeMap = {
|
||||
0: "Error",
|
||||
1: "Auto",
|
||||
2: "POC",
|
||||
3: "Timer",
|
||||
4: "Manual",
|
||||
5: "DH PID"
|
||||
}
|
||||
|
||||
|
||||
with open('/mnt/usb/setpoints.csv', 'w') as setpoint_file:
|
||||
wr = csv.writer(setpoint_file)
|
||||
stroke_time = time.time()
|
||||
dt = datetime.fromtimestamp(stroke_time)
|
||||
wr.writerow(['localtime', dt])
|
||||
wr.writerow(['utctime', datetime.utcfromtimestamp(stroke_time)])
|
||||
wr.writerow(['Mode', ReadFromPLC("Pump.Mode", "INT")])
|
||||
wr.writerow(['Speed_Setpoint_SPM', ReadFromPLC("Pump.Speed_Setpoint_SPM", "REAL")])
|
||||
wr.writerow(['Speed_Max', ReadFromPLC("Pump.Speed_Max", "REAL")])
|
||||
wr.writerow(['Speed_Min', ReadFromPLC("Pump.Speed_Min", "REAL")])
|
||||
wr.writerow(['Auto-Speed_Startpoint_SPM', ReadFromPLC("Pump.Speed_Startpoint_SPM_Auto", "REAL")])
|
||||
wr.writerow(['Auto-Percentage_Ramp_Down', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Increment_Ramp_Down', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Up', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Down', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Min_Speed_Strokes', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Up', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-POC-Startup_Ignore_Cards', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-POC-Card_Quantity', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['Auto-Percent_Ramp_Up', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
wr.writerow(['POC-Percent_Pumpoff', ReadFromPLC("Pump.Mode", "REAL")])
|
||||
|
||||
|
||||
cards_read = 1
|
||||
read_tapers = False
|
||||
already_gauged_off = False
|
||||
already_entered_well_test = False
|
||||
while True:
|
||||
now = datetime.now()
|
||||
with open('/mnt/usb/status.txt', 'w') as status_file:
|
||||
status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.strftime(now,"%Y%m%d_%H%M%S"), ReadFromPLC("Pump.Run_Status", "INT"),ReadFromPLC("Card_Past[1].ID", "INT"),ReadFromPLC("Card_Past[1].Fillage_Percent", "REAL"),ReadFromPLC("Card_Past[1].Fluid_Above_Pump", "REAL"),ReadFromPLC("Stroke_Production", "REAL")))
|
||||
#status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.now(), ReadFromPLC("Pump.Run_Status", "INT"),ReadFromPLC("Card_Past[1].ID", "INT"),ReadFromPLC("Card_Past[1].Fillage_Percent", "REAL"),ReadFromPLC("Card_Past[1].Fluid_Above_Pump", "REAL"),ReadFromPLC("Stroke_Production", "REAL")))
|
||||
|
||||
#############
|
||||
# CARD DATA #
|
||||
#############
|
||||
|
||||
EOS = ReadFromPLC("End_Of_Stroke", "INT")
|
||||
Already_Read = ReadFromPLC("Card_Past[1].Data_Read", "INT") > 0
|
||||
num_points = ReadFromPLC("Card_Past[1].Num_Points", "INT")
|
||||
|
||||
|
||||
if (EOS and not Already_Read and (EOS != 911)):
|
||||
stroke_time = time.time()
|
||||
dt = datetime.fromtimestamp(stroke_time)
|
||||
data['localtime'] = dt
|
||||
data['Stroke_Time'] = dt
|
||||
data['utctime'] = datetime.utcfromtimestamp(stroke_time)
|
||||
for t in tags_to_read:
|
||||
data[t[2]] = ReadFromPLC(t[0], t[1])
|
||||
|
||||
data['Surface_Position'] = []
|
||||
data['Surface_Load'] = []
|
||||
data['Downhole_Position'] = []
|
||||
data['Downhole_Load'] = []
|
||||
|
||||
for i in range(1, num_points-1):
|
||||
data['Surface_Position'].append(round(ReadFromPLC("Card_Past[1].Surface_Position[" + str(i) + "]", "REAL"),3))
|
||||
data['Surface_Load'].append(round(ReadFromPLC("Card_Past[1].Surface_Load[" + str(i) + "]", "REAL"),3))
|
||||
data['Downhole_Position'].append(round(ReadFromPLC("Card_Past[1].Downhole_Position[" + str(i) + "]", "REAL"),3))
|
||||
data['Downhole_Load'].append(round(ReadFromPLC("Card_Past[1].Downhole_Load[" + str(i) + "]", "REAL"),3))
|
||||
|
||||
st = datetime.strftime(dt,"%Y%m%d_%H%M%S")
|
||||
date = datetime.strftime(dt,"%Y%m%d")
|
||||
|
||||
if (data["Card_Type"] == 0):
|
||||
data["Card_Type"] = "Normal"
|
||||
elif (data["Card_Type"]== 1):
|
||||
data["Card_Type"] = "Shutdown"
|
||||
elif (data["Card_Type"]== 2):
|
||||
data["Card_Type"] = "Alarm"
|
||||
elif (data["Card_Type"]== 3):
|
||||
data["Card_Type"] = "Startup"
|
||||
else:
|
||||
data["Card_Type"] ="Unknown"
|
||||
|
||||
mode = 'torque'
|
||||
if data['Drive_Torque_Mode'] == 0:
|
||||
mode = 'speed'
|
||||
data['Drive_Reference'] = ReadFromPLC(mode_tags[mode][0], mode_tags[mode][1])
|
||||
|
||||
data['sp_string'] = ','.join(map(str, data['Surface_Position']))
|
||||
data['sl_string'] = ','.join(map(str, data['Surface_Load']))
|
||||
data['dp_string'] = ','.join(map(str, data['Downhole_Position']))
|
||||
data['dl_string'] = ','.join(map(str, data['Downhole_Load']))
|
||||
|
||||
insert_query = ("INSERT INTO WellData.card_history "
|
||||
"(Card_ID, Num_Tapers, Num_Points, Card_Type, Stroke_Time, Tubing_Head_Pressure, Fluid_Gradient, "
|
||||
"Stuffing_Box_Friction, dt, Downhole_Max_Load, Downhole_Min_Load, Downhole_Max_Position, Downhole_Min_Position, "
|
||||
"Downhole_Gross_Stroke, Downhole_Adjusted_Gross_Stroke, Downhole_Net_Stroke, Downhole_Fluid_Load, Surface_Max_Load, "
|
||||
"Surface_Min_Load, Surface_Max_Position, Surface_Min_Position, Tubing_Movement, Surface_Stroke_Length, Fillage_Percent, "
|
||||
"Polished_Rod_HP, Pump_HP, SPM, Fluid_Level, Pump_Intake_Pressure, Stroke_Production, Drive_Torque_Mode, Drive_Reference, "
|
||||
"Surface_Position, Surface_Load, Downhole_Position, Downhole_Load) VALUES "
|
||||
"(%(Card_ID)s, %(Num_Tapers)s, %(Num_Points)s, %(Card_Type)s, %(Stroke_Time)s, %(Tubing_Head_Pressure)s, %(Fluid_Gradient)s, "
|
||||
"%(Stuffing_Box_Friction)s, %(dt)s, %(Downhole_Max_Load)s, %(Downhole_Min_Load)s, %(Downhole_Max_Position)s, %(Downhole_Min_Position)s, "
|
||||
"%(Downhole_Gross_Stroke)s, %(Downhole_Adjusted_Gross_Stroke)s, %(Downhole_Net_Stroke)s, %(Downhole_Fluid_Load)s, %(Surface_Max_Load)s, "
|
||||
"%(Surface_Min_Load)s, %(Surface_Max_Position)s, %(Surface_Min_Position)s, %(Tubing_Movement)s, %(Surface_Stroke_Length)s, %(Fillage_Percent)s, "
|
||||
"%(Polished_Rod_HP)s, %(Pump_HP)s, %(SPM)s, %(Fluid_Level)s, %(Pump_Intake_Pressure)s, %(Stroke_Production)s, %(Drive_Torque_Mode)s, %(Drive_Reference)s, "
|
||||
"%(sp_string)s, %(sl_string)s, %(dp_string)s, %(dl_string)s)")
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
cur.execute(insert_query, data)
|
||||
db.commit()
|
||||
db.close()
|
||||
tux.WriteLGXData(sess, conn, "Card_Past[1].Data_Read", LGX_REAL, 1, 1)
|
||||
print "CARD NUMBER " + str(data["Card_ID"]) + " READ!"
|
||||
|
||||
|
||||
##############
|
||||
# TAPER DATA #
|
||||
##############
|
||||
|
||||
update_taper = ReadFromPLC("Write_Tapers", "INT")
|
||||
if (update_taper == 0):
|
||||
if read_tapers:
|
||||
read_tapers = False
|
||||
print "Update Tapers = False"
|
||||
|
||||
if (update_taper and (not read_tapers) and (update_taper != 911)):
|
||||
print "reading taper file"
|
||||
taper_count = 0;
|
||||
|
||||
tFilename = path_to_CSV + "CSV/TAPER/TAPER_" + datetime.strftime(now,"%Y%m%d_%H%M%S")+ '.CSV'
|
||||
tFile = open(tFilename, 'wb')
|
||||
twr = csv.writer(tFile, quoting=csv.QUOTE_ALL)
|
||||
for taps in range(1,10):
|
||||
taper_in_use_temp = ReadFromPLC('Taper.Taper[' + str(taps)+'].Calculated.InUse', "INT")
|
||||
if taper_in_use_temp:
|
||||
taper_count = taper_count + 1
|
||||
#print "reading Taper"+ str(taper_count)
|
||||
twr.writerow(["Taper",taper_count])
|
||||
twr.writerow(['Length',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Length', 'REAL')])
|
||||
twr.writerow(['Diameter',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Diameter', 'REAL')])
|
||||
tMaterial = ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Material', 'INT')
|
||||
if (tMaterial == 1):
|
||||
twr.writerow(['Material',"Steel"])
|
||||
elif (tMaterial == 2):
|
||||
twr.writerow(['Material',"Fiberglass"])
|
||||
twr.writerow(['Weight_Per_Foot', ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Weight', 'REAL')])
|
||||
twr.writerow(['Youngs_Modulus',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.Youngs_Modulus', 'REAL')])
|
||||
twr.writerow(['Damping_Factor',ReadFromPLC('Taper.Taper['+str(taps) +'].Setup.c', 'REAL')])
|
||||
twr.writerow(['Area',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Area', 'REAL')])
|
||||
twr.writerow(['Rod_Depth',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Rod_Depth', 'REAL')])
|
||||
twr.writerow(['Pressure',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Pressure', 'REAL')])
|
||||
twr.writerow(['Buoyant_Force',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Buoyant_Force', 'REAL')])
|
||||
twr.writerow(['Rod_Weight',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Rod_Weight_Air', 'REAL')])
|
||||
twr.writerow(['Force',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Force', 'REAL')])
|
||||
twr.writerow(['Stretch',ReadFromPLC('Taper.Taper['+str(taps) +'].Calculated.Stretch', 'REAL')])
|
||||
twr.writerow(["",""])
|
||||
else:
|
||||
break
|
||||
twr.writerow(["UnitConfig",""])
|
||||
twr.writerow(['Pump_Diameter',ReadFromPLC('UnitConfig.Pump_Diameter', 'REAL')])
|
||||
tFile.close()
|
||||
read_tapers = True
|
||||
print "TAPER DATA READ: "+ tFilename
|
||||
|
||||
##################
|
||||
# GAUGE OFF DATA #
|
||||
##################
|
||||
gauge_off = ReadFromPLC("Gauge_Off_Command", "INT")
|
||||
if (gauge_off == 0):
|
||||
if already_gauged_off:
|
||||
already_gauged_off = False
|
||||
print "Already gauged off... Setting gauge_off to False"
|
||||
|
||||
if (gauge_off and (not already_gauged_off) and (gauge_off != 911)):
|
||||
print "Gauging off..."
|
||||
gYear = ReadFromPLC("GAUGEOFF_DateTime.Year", "INT")
|
||||
gMonth = ReadFromPLC("GAUGEOFF_DateTime.Month", "INT")
|
||||
gDay = ReadFromPLC("GAUGEOFF_DateTime.Day", "INT")
|
||||
gHour = ReadFromPLC("GAUGEOFF_DateTime.Hour", "INT")
|
||||
gMin = ReadFromPLC("GAUGEOFF_DateTime.Min", "INT")
|
||||
gSec = ReadFromPLC("GAUGEOFF_DateTime.Sec", "INT")
|
||||
gauge_date = datetime(year = gYear, month = gMonth,day = gDay,hour = gHour,minute = gMin,second = gSec)
|
||||
percent_run = round(ReadFromPLC("GAUGEOFF_Percent_Run", "REAL"),2)
|
||||
kWh = round(ReadFromPLC("GAUGEOFF_kWh", "REAL"),3)
|
||||
electricity_cost = round(ReadFromPLC("GAUGEOFF_Electricity_Cost", "REAL"),2)
|
||||
peak_load = round(ReadFromPLC("GAUGEOFF_Max_Load", "REAL"),3)
|
||||
min_load = round(ReadFromPLC("GAUGEOFF_Min_Load", "REAL"),3)
|
||||
average_SPM = round(ReadFromPLC("GAUGEOFF_Average_SPM", "REAL"),4)
|
||||
production_calculated = round(ReadFromPLC("GAUGEOFF_Production_Calculated", "REAL"),2)
|
||||
full_card_production = round(ReadFromPLC("GAUGEOFF_Full_Card_Production", "REAL"),2)
|
||||
polished_rod_HP = round(ReadFromPLC("GAUGEOFF_Polished_Rod_HP", "REAL"),3)
|
||||
lifting_cost = round(ReadFromPLC("GAUGEOFF_Lifting_Cost", "REAL"),4)
|
||||
fluid_above_pump = round(ReadFromPLC("GAUGEOFF_Fluid_Above_Pump", "REAL"),2)
|
||||
pump_intake_pressure = round(ReadFromPLC("GAUGEOFF_pump_intake_pressure", "REAL"),2)
|
||||
kWh_regen = round(ReadFromPLC("GAUGEOFF_kWh_regen", "REAL"),2)
|
||||
inflow_rate = round(ReadFromPLC("GAUGEOFF_Inflow_Rate", "REAL"),4)
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
print """INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate)
|
||||
storeHist = cur.execute("""INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate))
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_gauged_off = True
|
||||
print "Gauged off!"
|
||||
|
||||
|
||||
##################
|
||||
# WELL TEST DATA #
|
||||
##################
|
||||
|
||||
well_test_entered = ReadFromPLC("Well_Test.Test_Submit", "INT")
|
||||
if (well_test_entered == 0):
|
||||
if already_entered_well_test:
|
||||
already_entered_well_test = False
|
||||
print "Already entered well Test... Setting well_test_entered to False"
|
||||
if (well_test_entered and (not already_entered_well_test) and well_test_entered != 911):
|
||||
print "Well Test Entered"
|
||||
|
||||
tYear = ReadFromPLC("Well_Test.DateTime_Complete.Year", "INT")
|
||||
tMonth = ReadFromPLC("Well_Test.DateTime_Complete.Month", "INT")
|
||||
tDay = ReadFromPLC("Well_Test.DateTime_Complete.Day", "INT")
|
||||
tHour = ReadFromPLC("Well_Test.DateTime_Complete.Hour", "INT")
|
||||
tMin = ReadFromPLC("Well_Test.DateTime_Complete.Min", "INT")
|
||||
tSec = ReadFromPLC("Well_Test.DateTime_Complete.Sec", "INT")
|
||||
test_date = datetime(year = tYear, month = tMonth,day = tDay,hour = tHour,minute = tMin,second = tSec)
|
||||
test_duration = round(ReadFromPLC("Well_Test.Test_Duration", "REAL"),3)
|
||||
v_water = round(ReadFromPLC("Well_Test.Volume_Water", "REAL"),3)
|
||||
v_oil = round(ReadFromPLC("Well_Test.Volume_Oil", "REAL"),3)
|
||||
v_gas = round(ReadFromPLC("Well_Test.Volume_Gas", "REAL"),3)
|
||||
p_v_water = round(ReadFromPLC("Well_Test.Projected_Volume_Water", "REAL"),3)
|
||||
p_v_oil = round(ReadFromPLC("Well_Test.Projected_Volume_Oil", "REAL"),3)
|
||||
k_factor = round(ReadFromPLC("Well_Test.k_Factor", "REAL"),3)
|
||||
api_oil = round(ReadFromPLC("Well_Test.API_Oil", "REAL"),3)
|
||||
sg_water = round(ReadFromPLC("Well_Test.SG_Water", "REAL"),3)
|
||||
|
||||
db = MySQLdb.connect(host="localhost",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
test_query = "INSERT INTO WellData.Well_Test (test_date, test_volume_oil, test_volume_water, test_volume_gas, k_factor, projected_volume_oil, projected_volume_water, api_gravity_oil, sg_water, test_hours) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}');".format(test_date, v_oil, v_water, v_gas, k_factor, p_v_oil, p_v_water, api_oil, sg_water, test_duration)
|
||||
print test_query
|
||||
storeTest = cur.execute(test_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_entered_well_test = True
|
||||
print "Well Test Stored!"
|
||||
|
||||
time.sleep(.20)
|
||||
330
dataLogger_pycomm.py
Normal file
330
dataLogger_pycomm.py
Normal file
@@ -0,0 +1,330 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
|
||||
#from prettytable import PrettyTable
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
import time
|
||||
import MySQLdb
|
||||
|
||||
def main():
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
try:
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
except:
|
||||
print("PLC Address not set in database... using default of 192.168.1.10")
|
||||
PLC_IP_ADDRESS = "192.168.1.10"
|
||||
PLC_TYPE = "VFD"
|
||||
|
||||
sys.path.append("../")
|
||||
|
||||
path_to_CSV = "/mnt/usb/"
|
||||
|
||||
#PYCOMM Connection to PLC
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
|
||||
|
||||
|
||||
if os.path.exists(path_to_CSV + "current.csv"):
|
||||
os.remove(path_to_CSV + "current.csv")
|
||||
|
||||
|
||||
tags_to_read = [['Card_Past[1].ID', 'INT', "Card_ID"],
|
||||
['Card_Past[1].Params.Num_Tapers', 'INT', 'Num_Tapers'],
|
||||
['Card_Past[1].Num_Points', 'INT', 'Num_Points'],
|
||||
['Card_Past[1].Card_Type', 'INT', 'Card_Type'],
|
||||
['Card_Past[1].End_Time.Year', 'INT', '_Year'],
|
||||
['Card_Past[1].End_Time.Month', 'INT', '_Month'],
|
||||
['Card_Past[1].End_Time.Day', 'INT', '_Day'],
|
||||
['Card_Past[1].End_Time.Hour', 'INT', '_Hour'],
|
||||
['Card_Past[1].End_Time.Min', 'INT', '_Minute'],
|
||||
['Card_Past[1].End_Time.Sec', 'INT', '_Second'],
|
||||
#['Card_Past[1].Name.Data[0]','STRING', 'Well_Name'],
|
||||
['Card_Past[1].Params.Tubing_Head_Pressure','REAL', 'Tubing_Head_Pressure'],
|
||||
['Card_Past[1].Params.Fluid_Gradient','REAL', 'Fluid_Gradient'],
|
||||
['Card_Past[1].Params.Stuffing_Box_Friction','REAL', 'Stuffing_Box_Friction'],
|
||||
['Card_Past[1].Params.dt','REAL', 'dt'],
|
||||
# ['Card_Past[1].Downhole_Max_Load.Load','REAL', 'Downhole_Max_Load'],
|
||||
# ['Card_Past[1].Downhole_Min_Load.Load','REAL', 'Downhole_Min_Load'],
|
||||
# ['Card_Past[1].Downhole_Max_Position.Position','REAL', 'Downhole_Max_Position'],
|
||||
# ['Card_Past[1].Downhole_Min_Position.Position','REAL', 'Downhole_Min_Position'],
|
||||
['Card_Past[1].Downhole_GrossStroke','REAL', 'Downhole_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_AdjustedGrossStroke','REAL', 'Downhole_Adjusted_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_NetStroke','REAL', 'Downhole_Net_Stroke'],
|
||||
['Card_Past[1].Downhole_FluidLoad','REAL', 'Downhole_Fluid_Load'],
|
||||
['Card_Past[1].Surface_Max.Load','REAL', 'Surface_Max_Load'],
|
||||
['Card_Past[1].Surface_Min.Load','REAL', 'Surface_Min_Load'],
|
||||
# ['Card_Past[1].Surface_Max.Position','REAL', 'Surface_Max_Position'],
|
||||
# ['Card_Past[1].Surface_Min.Position','REAL', 'Surface_Min_Position'],
|
||||
['Card_Past[1].Tubing_Movement','REAL', 'Tubing_Movement'],
|
||||
['Card_Past[1].Surface_StrokeLength','REAL', 'Surface_Stroke_Length'],
|
||||
['Card_Past[1].Fillage_Percent','REAL', 'Fillage_Percent'],
|
||||
['Card_Past[1].Polished_Rod_HP','REAL', 'Polished_Rod_HP'],
|
||||
['Card_Past[1].Pump_HP','REAL', 'Pump_HP'],
|
||||
['Card_Past[1].SPM','REAL', 'SPM'],
|
||||
['Card_Past[1].Fluid_Above_Pump','REAL', 'Fluid_Above_Pump'],
|
||||
['Stroke_Production','REAL', 'Stroke_Production'],
|
||||
['Pump_Intake_Pressure','REAL', 'Pump_Intake_Pressure'],
|
||||
]
|
||||
|
||||
def readString(tag):
|
||||
read_vals = c.read_array(tag, 82)
|
||||
string = filter(lambda b: b != "",map(lambda a: chr(a[1]),read_vals))
|
||||
return "".join(string)
|
||||
|
||||
|
||||
cards_read = 1
|
||||
read_tapers = False
|
||||
already_gauged_off = False
|
||||
already_entered_well_test = False
|
||||
try:
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
while True:
|
||||
data = {}
|
||||
|
||||
now = datetime.now()
|
||||
run_status = c.read_tag(['Pump.Run_Status'])[0][1]
|
||||
card_id = c.read_tag(['Card_Past[1].ID'])[0][1]
|
||||
fillage_percent = c.read_tag(['Card_Past[1].Fillage_Percent'])[0][1]
|
||||
fluid_above_pump = c.read_tag(['Card_Past[1].Fluid_Above_Pump'])[0][1]
|
||||
stroke_production = c.read_tag(['Stroke_Production'])[0][1]
|
||||
with open('/mnt/usb/status.txt', 'w') as status_file:
|
||||
status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.strftime(now,"%Y%m%d_%H%M%S"), run_status, card_id, fillage_percent, fluid_above_pump, stroke_production))
|
||||
|
||||
#############
|
||||
# CARD DATA #
|
||||
#############
|
||||
|
||||
EOS = c.read_tag(["End_Of_Stroke"])[0][1]
|
||||
Already_Read = c.read_tag(["Card_Past[1].Data_Read"])[0][1] > 0
|
||||
|
||||
if (EOS and not Already_Read and (EOS != 911)):
|
||||
num_points = c.read_tag(["Card_Past[1].Num_Points"])[0][1]
|
||||
data['Well_Name'] = readString('Card_Past[1].Name.Data')
|
||||
filename = path_to_CSV + "current.csv"
|
||||
myfile = open(filename, 'wb')
|
||||
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
|
||||
stroke_time = time.time()
|
||||
dt = datetime.fromtimestamp(stroke_time)
|
||||
wr.writerow(['localtime', dt])
|
||||
wr.writerow(['utctime', datetime.utcfromtimestamp(stroke_time)])
|
||||
# wr.writerow(["Well_Name",data["Well_Name"]])
|
||||
for t in tags_to_read:
|
||||
data[t[2]] = c.read_tag([t[0]])[0][1]
|
||||
wr.writerow([t[2],data[t[2]]])
|
||||
numPointsRead = num_points + 1
|
||||
sp = c.read_array("Card_Past[0].Surface_Position", numPointsRead)
|
||||
sl = c.read_array("Card_Past[0].Surface_Load", numPointsRead)
|
||||
dp = c.read_array("Card_Past[0].Downhole_Position", numPointsRead)
|
||||
dl = c.read_array("Card_Past[0].Downhole_Load", numPointsRead)
|
||||
wr.writerow(["s_pos", "s_load"])
|
||||
for i in range(0, numPointsRead):
|
||||
if sp[i][1] and (sp[i][1] != 0.0) and sl[i][1]:
|
||||
wr.writerow([round(sp[i][1],3), round(sl[i][1],3)])
|
||||
wr.writerow(["d_pos", "d_load"])
|
||||
for i in range(1, numPointsRead):
|
||||
if dp[i][1] and (dp[i][1] != 0.0) and dl[i][1]:
|
||||
wr.writerow([round(dp[i][1],3), round(dl[i][1],3)])
|
||||
myfile.close()
|
||||
dt = datetime(year = data["_Year"], month = data["_Month"],day = data["_Day"],hour = data["_Hour"],minute = data["_Minute"],second = data["_Second"])
|
||||
st = datetime.strftime(dt,"%Y%m%d_%H%M%S")
|
||||
date = datetime.strftime(dt,"%Y%m%d")
|
||||
|
||||
if (data["Card_Type"] == 0):
|
||||
data["Card_Type"] = "Normal"
|
||||
elif (data["Card_Type"]==1):
|
||||
data["Card_Type"] = "Shutdown"
|
||||
elif (data["Card_Type"]==2):
|
||||
data["Card_Type"] = "Alarm"
|
||||
elif (data["Card_Type"]==3):
|
||||
data["Card_Type"] = "Startup"
|
||||
else:
|
||||
data["Card_Type"] ="Unknown"
|
||||
|
||||
if not os.path.exists(path_to_CSV +"CSV/"+date):
|
||||
os.makedirs(path_to_CSV+"CSV/"+date)
|
||||
|
||||
fill_percent_file = str(round(data['Fillage_Percent'],3)).replace(".","-")
|
||||
rename_file = path_to_CSV+"CSV/"+ date+"/"+st+"_"+str(data["Card_ID"])+"_"+data['Card_Type']+ "_"+fill_percent_file +".csv"
|
||||
os.rename(filename, rename_file)
|
||||
|
||||
c.write_tag('Card_Past[1].Data_Read', 1, 'REAL')
|
||||
print "CARD NUMBER " + str(cards_read) + " READ: "+str(data["Card_ID"])+ ", STORED AS "+ rename_file
|
||||
cards_read = cards_read + 1
|
||||
|
||||
|
||||
##############
|
||||
# TAPER DATA #
|
||||
##############
|
||||
update_taper = c.read_tag(["Write_Tapers"])[0][1]
|
||||
if (update_taper == 0):
|
||||
if read_tapers:
|
||||
read_tapers = False
|
||||
print "Update Tapers = False"
|
||||
|
||||
if (update_taper and (not read_tapers) and (update_taper != 911)):
|
||||
print "reading taper file"
|
||||
taper_count = 0;
|
||||
|
||||
tFilename = path_to_CSV + "CSV/TAPER/TAPER_" + datetime.strftime(now,"%Y%m%d_%H%M%S")+ '.CSV'
|
||||
tFile = open(tFilename, 'wb')
|
||||
twr = csv.writer(tFile, quoting=csv.QUOTE_ALL)
|
||||
for taps in range(1,10):
|
||||
taper_in_use_temp = c.read_tag(['Taper.Taper[' + str(taps)+'].Calculated.InUse'])[0][1]
|
||||
if taper_in_use_temp:
|
||||
taper_count = taper_count + 1
|
||||
#print "reading Taper"+ str(taper_count)
|
||||
twr.writerow(["Taper",taper_count])
|
||||
twr.writerow(['Length',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Length'])[0][1]])
|
||||
twr.writerow(['Diameter',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Diameter'])[0][1]])
|
||||
tMaterial = c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Material'])[0][1]
|
||||
if (tMaterial == 1):
|
||||
twr.writerow(['Material',"Steel"])
|
||||
elif (tMaterial == 2):
|
||||
twr.writerow(['Material',"Fiberglass"])
|
||||
twr.writerow(['Weight_Per_Foot', c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Weight'])[0][1]])
|
||||
twr.writerow(['Youngs_Modulus',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Youngs_Modulus'])[0][1]])
|
||||
twr.writerow(['Damping_Factor',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.c'])[0][1]])
|
||||
twr.writerow(['Area',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Area'])[0][1]])
|
||||
twr.writerow(['Rod_Depth',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Rod_Depth'])[0][1]])
|
||||
twr.writerow(['Pressure',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Pressure'])[0][1]])
|
||||
twr.writerow(['Buoyant_Force',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Buoyant_Force'])[0][1]])
|
||||
twr.writerow(['Rod_Weight',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Rod_Weight_Air'])[0][1]])
|
||||
twr.writerow(['Force',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Force'])[0][1]])
|
||||
twr.writerow(['Stretch',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Stretch'])[0][1]])
|
||||
twr.writerow(["",""])
|
||||
else:
|
||||
break
|
||||
twr.writerow(["UnitConfig",""])
|
||||
twr.writerow(['Pump_Diameter',c.read_tag(['UnitConfig.Pump_Diameter'])[0][1]])
|
||||
tFile.close()
|
||||
read_tapers = True
|
||||
print "TAPER DATA READ: "+ tFilename
|
||||
|
||||
##################
|
||||
# GAUGE OFF DATA #
|
||||
##################
|
||||
gauge_off = c.read_tag(['Gauge_Off_Command'])[0][1]
|
||||
if (gauge_off == 0):
|
||||
if already_gauged_off:
|
||||
already_gauged_off = False
|
||||
print "Already gauged off... Setting gauge_off to False"
|
||||
|
||||
if (gauge_off and (not already_gauged_off)):
|
||||
print "Gauging off..."
|
||||
gYear = c.read_tag(['GAUGEOFF_DateTime.Year'])[0][1]
|
||||
gMonth = c.read_tag(['GAUGEOFF_DateTime.Month'])[0][1]
|
||||
gDay = c.read_tag(['GAUGEOFF_DateTime.Day'])[0][1]
|
||||
gHour = c.read_tag(['GAUGEOFF_DateTime.Hour'])[0][1]
|
||||
gMin = c.read_tag(['GAUGEOFF_DateTime.Min'])[0][1]
|
||||
gSec = c.read_tag(['GAUGEOFF_DateTime.Sec'])[0][1]
|
||||
gauge_date = datetime(year = gYear, month = gMonth,day = gDay,hour = gHour,minute = gMin,second = gSec)
|
||||
print "gaugeDate: {0}".format(gauge_date)
|
||||
percent_run = round(c.read_tag(['GAUGEOFF_Percent_Run'])[0][1],2)
|
||||
print "percent_run: {0}".format(percent_run)
|
||||
kWh = round(c.read_tag(['GAUGEOFF_kWh'])[0][1],3)
|
||||
print "kWh: {0}".format(kWh)
|
||||
electricity_cost = round(c.read_tag(['GAUGEOFF_Electricity_Cost'])[0][1],2)
|
||||
print "electricity_cost: {0}".format(electricity_cost)
|
||||
peak_load = round(c.read_tag(['GAUGEOFF_Max_Load'])[0][1],3)
|
||||
print "peak_load: {0}".format(peak_load)
|
||||
min_load = round(c.read_tag(['GAUGEOFF_Min_Load'])[0][1],3)
|
||||
print "min_load: {0}".format(min_load)
|
||||
average_SPM = round(c.read_tag(['GAUGEOFF_Average_SPM'])[0][1],4)
|
||||
print "average_SPM: {0}".format(average_SPM)
|
||||
production_calculated = round(c.read_tag(['GAUGEOFF_Production_Calculated'])[0][1],2)
|
||||
print "production_calculated: {0}".format(production_calculated)
|
||||
full_card_production = round(c.read_tag(['GAUGEOFF_Full_Card_Production'])[0][1],2)
|
||||
print "full_card_production: {0}".format(full_card_production)
|
||||
polished_rod_HP = round(c.read_tag(['GAUGEOFF_Polished_Rod_HP'])[0][1],3)
|
||||
print "polished_rod_HP: {0}".format(polished_rod_HP)
|
||||
lifting_cost = round(c.read_tag(['GAUGEOFF_Lifting_Cost'])[0][1],4)
|
||||
print "lifting_cost: {0}".format(lifting_cost)
|
||||
fluid_above_pump = round(c.read_tag(['GAUGEOFF_Fluid_Above_Pump'])[0][1],2)
|
||||
print "fluid_above_pump: {0}".format(fluid_above_pump)
|
||||
pump_intake_pressure = round(c.read_tag(['GAUGEOFF_pump_intake_pressure'])[0][1],2)
|
||||
print "pump_intake_pressure: {0}".format(pump_intake_pressure)
|
||||
kWh_regen = round(c.read_tag(['GAUGEOFF_kWh_regen'])[0][1],2)
|
||||
print "kWh_regen: {0}".format(kWh_regen)
|
||||
inflow_rate = round(c.read_tag(['GAUGEOFF_Inflow_Rate'])[0][1],4)
|
||||
print "inflow_rate: {0}".format(inflow_rate)
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
print """INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate)
|
||||
storeHist = cur.execute("""INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate))
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_gauged_off = True
|
||||
print "Gauged off!"
|
||||
|
||||
|
||||
# ##################
|
||||
# # WELL TEST DATA #
|
||||
# ##################
|
||||
|
||||
well_test_entered = c.read_tag(['Well_Test.Test_Submit'])[0][1]
|
||||
if (well_test_entered == 0):
|
||||
if already_entered_well_test:
|
||||
already_entered_well_test = False
|
||||
print "Already entered well Test... Setting well_test_entered to False"
|
||||
if (well_test_entered and (not already_entered_well_test) and well_test_entered != 911):
|
||||
print "Well Test Entered"
|
||||
|
||||
tYear = c.read_tag(['Well_Test.DateTime_Complete.Year'])[0][1]
|
||||
tMonth = c.read_tag(['Well_Test.DateTime_Complete.Month'])[0][1]
|
||||
tDay = c.read_tag(['Well_Test.DateTime_Complete.Day'])[0][1]
|
||||
tHour = c.read_tag(['Well_Test.DateTime_Complete.Hour'])[0][1]
|
||||
tMin = c.read_tag(['Well_Test.DateTime_Complete.Min'])[0][1]
|
||||
tSec = c.read_tag(['Well_Test.DateTime_Complete.Sec'])[0][1]
|
||||
test_date = datetime(year = tYear, month = tMonth,day = tDay,hour = tHour,minute = tMin,second = tSec)
|
||||
test_duration = round(c.read_tag(['Well_Test.Test_Duration'])[0][1],3)
|
||||
v_water = round(c.read_tag(['Well_Test.Volume_Water'])[0][1],3)
|
||||
v_oil = round(c.read_tag(['Well_Test.Volume_Oil'])[0][1],3)
|
||||
v_gas = round(c.read_tag(['Well_Test.Volume_Gas'])[0][1],3)
|
||||
p_v_water = round(c.read_tag(['Well_Test.Projected_Volume_Water'])[0][1],3)
|
||||
p_v_oil = round(c.read_tag(['Well_Test.Projected_Volume_Oil'])[0][1],3)
|
||||
k_factor = round(c.read_tag(['Well_Test.k_Factor'])[0][1],3)
|
||||
api_oil = round(c.read_tag(['Well_Test.API_Oil'])[0][1],3)
|
||||
sg_water = round(c.read_tag(['Well_Test.SG_Water'])[0][1],3)
|
||||
|
||||
db = MySQLdb.connect(host="localhost",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
test_query = "INSERT INTO WellData.Well_Test (test_date, test_volume_oil, test_volume_water, test_volume_gas, k_factor, projected_volume_oil, projected_volume_water, api_gravity_oil, sg_water, test_hours) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}');".format(test_date, v_oil, v_water, v_gas, k_factor, p_v_oil, p_v_water, api_oil, sg_water, test_duration)
|
||||
print test_query
|
||||
storeTest = cur.execute(test_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_entered_well_test = True
|
||||
print "Well Test Stored!"
|
||||
|
||||
time.sleep(.20)
|
||||
except Exception, e:
|
||||
print("FATAL ERROR: Communication Error connecting to the PLC... ", e)
|
||||
c.forward_close()
|
||||
c.open(PLC_IP_ADDRESS)
|
||||
main()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
297
dataLogger_pycomm_mysql.py
Normal file
297
dataLogger_pycomm_mysql.py
Normal file
@@ -0,0 +1,297 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
|
||||
#from prettytable import PrettyTable
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
from time import sleep
|
||||
import MySQLdb
|
||||
|
||||
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
|
||||
sys.path.append("../")
|
||||
|
||||
path_to_CSV = "/mnt/usb/"
|
||||
|
||||
#PYCOMM Connection to PLC
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
|
||||
|
||||
|
||||
if os.path.exists(path_to_CSV + "current.csv"):
|
||||
os.remove(path_to_CSV + "current.csv")
|
||||
|
||||
|
||||
tags_to_read = [['Card_Past[1].ID', 'INT', "Card_ID"],
|
||||
['Card_Past[1].Params.Num_Tapers', 'INT', 'Num_Tapers'],
|
||||
['Card_Past[1].Num_Points', 'INT', 'Num_Points'],
|
||||
['Card_Past[1].Card_Type', 'INT', 'Card_Type'],
|
||||
['Card_Past[1].End_Time.Year', 'INT', '_Year'],
|
||||
['Card_Past[1].End_Time.Month', 'INT', '_Month'],
|
||||
['Card_Past[1].End_Time.Day', 'INT', '_Day'],
|
||||
['Card_Past[1].End_Time.Hour', 'INT', '_Hour'],
|
||||
['Card_Past[1].End_Time.Min', 'INT', '_Minute'],
|
||||
['Card_Past[1].End_Time.Sec', 'INT', '_Second'],
|
||||
#['Card_Past[1].Name.Data[0]','STRING', 'Well_Name'],
|
||||
['Card_Past[1].Params.Tubing_Head_Pressure','REAL', 'Tubing_Head_Pressure'],
|
||||
['Card_Past[1].Params.Fluid_Gradient','REAL', 'Fluid_Gradient'],
|
||||
['Card_Past[1].Params.Stuffing_Box_Friction','REAL', 'Stuffing_Box_Friction'],
|
||||
['Card_Past[1].Params.dt','REAL', 'dt'],
|
||||
['Card_Past[1].Downhole_Max_Load.Load','REAL', 'Downhole_Max_Load'],
|
||||
['Card_Past[1].Downhole_Min_Load.Load','REAL', 'Downhole_Min_Load'],
|
||||
['Card_Past[1].Downhole_Max_Position.Position','REAL', 'Downhole_Max_Position'],
|
||||
['Card_Past[1].Downhole_Min_Position.Position','REAL', 'Downhole_Min_Position'],
|
||||
['Card_Past[1].Downhole_GrossStroke','REAL', 'Downhole_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_AdjustedGrossStroke','REAL', 'Downhole_Adjusted_Gross_Stroke'],
|
||||
['Card_Past[1].Downhole_NetStroke','REAL', 'Downhole_Net_Stroke'],
|
||||
['Card_Past[1].Downhole_FluidLoad','REAL', 'Downhole_Fluid_Load'],
|
||||
['Card_Past[1].Surface_Max.Load','REAL', 'Surface_Max_Load'],
|
||||
['Card_Past[1].Surface_Min.Load','REAL', 'Surface_Min_Load'],
|
||||
['Card_Past[1].Surface_Max.Position','REAL', 'Surface_Max_Position'],
|
||||
['Card_Past[1].Surface_Min.Position','REAL', 'Surface_Min_Position'],
|
||||
['Card_Past[1].Tubing_Movement','REAL', 'Tubing_Movement'],
|
||||
['Card_Past[1].Surface_StrokeLength','REAL', 'Surface_Stroke_Length'],
|
||||
['Card_Past[1].Fillage_Percent','REAL', 'Fillage_Percent'],
|
||||
['Card_Past[1].Polished_Rod_HP','REAL', 'Polished_Rod_HP'],
|
||||
['Card_Past[1].Pump_HP','REAL', 'Pump_HP'],
|
||||
['Card_Past[1].SPM','REAL', 'SPM'],
|
||||
['Card_Past[1].Fluid_Above_Pump','REAL', 'Fluid_Above_Pump'],
|
||||
['Stroke_Production','REAL', 'Stroke_Production'],
|
||||
]
|
||||
|
||||
def readString(tag):
|
||||
read_vals = c.read_array(tag, 82)
|
||||
string = filter(lambda b: b != "",map(lambda a: chr(a[1]),read_vals))
|
||||
return "".join(string)
|
||||
|
||||
|
||||
cards_read = 1
|
||||
read_tapers = False
|
||||
already_gauged_off = False
|
||||
already_entered_well_test = False
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
while True:
|
||||
data = {}
|
||||
|
||||
now = datetime.now()
|
||||
run_status = c.read_tag(['Pump.Run_Status'])[0][1]
|
||||
card_id = c.read_tag(['Card_Past[1].ID'])[0][1]
|
||||
fillage_percent = c.read_tag(['Card_Past[1].Fillage_Percent'])[0][1]
|
||||
fluid_above_pump = c.read_tag(['Card_Past[1].Fluid_Above_Pump'])[0][1]
|
||||
stroke_production = c.read_tag(['Stroke_Production'])[0][1]
|
||||
with open('/mnt/usb/status.txt', 'w') as status_file:
|
||||
status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.strftime(now,"%Y%m%d_%H%M%S"), run_status, card_id, fillage_percent, fluid_above_pump, stroke_production))
|
||||
|
||||
#############
|
||||
# CARD DATA #
|
||||
#############
|
||||
|
||||
EOS = c.read_tag(["End_Of_Stroke"])[0][1]
|
||||
Already_Read = c.read_tag(["Card_Past[1].Data_Read"])[0][1] > 0
|
||||
|
||||
if (EOS and not Already_Read and (EOS != 911)):
|
||||
num_points = c.read_tag(["Card_Past[1].Num_Points"])[0][1]
|
||||
data['Well_Name'] = readString('Card_Past[1].Name.Data')
|
||||
filename = path_to_CSV + "current.csv"
|
||||
myfile = open(filename, 'wb')
|
||||
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
|
||||
wr.writerow(["Well_Name",data["Well_Name"]])
|
||||
for t in tags_to_read:
|
||||
data[t[2]] = c.read_tag([t[0]])[0][1]
|
||||
wr.writerow([t[2],data[t[2]]])
|
||||
numPointsRead = num_points + 1
|
||||
sp = c.read_array("Card_Past[0].Surface_Position", numPointsRead)
|
||||
sl = c.read_array("Card_Past[0].Surface_Load", numPointsRead)
|
||||
dp = c.read_array("Card_Past[0].Downhole_Position", numPointsRead)
|
||||
dl = c.read_array("Card_Past[0].Downhole_Load", numPointsRead)
|
||||
wr.writerow(["s_pos", "s_load"])
|
||||
for i in range(0, numPointsRead):
|
||||
if sp[i][1] != 0.0 and sl[i][1]:
|
||||
wr.writerow([round(sp[i][1],3), round(sl[i][1],3)])
|
||||
wr.writerow(["d_pos", "d_load"])
|
||||
for i in range(1, numPointsRead):
|
||||
if dp[i][1] != 0.0 and dl[i][1]:
|
||||
wr.writerow([round(dp[i][1],3), round(dl[i][1],3)])
|
||||
myfile.close()
|
||||
dt = datetime(year = data["_Year"], month = data["_Month"],day = data["_Day"],hour = data["_Hour"],minute = data["_Minute"],second = data["_Second"])
|
||||
st = datetime.strftime(dt,"%Y%m%d_%H%M%S")
|
||||
date = datetime.strftime(dt,"%Y%m%d")
|
||||
|
||||
if (data["Card_Type"] == 0):
|
||||
data["Card_Type"] = "Normal"
|
||||
elif (data["Card_Type"]==1):
|
||||
data["Card_Type"] = "Shutdown"
|
||||
elif (data["Card_Type"]==2):
|
||||
data["Card_Type"] = "Alarm"
|
||||
elif (data["Card_Type"]==3):
|
||||
data["Card_Type"] = "Startup"
|
||||
else:
|
||||
data["Card_Type"] ="Unknown"
|
||||
|
||||
if not os.path.exists(path_to_CSV +"CSV/"+date):
|
||||
os.makedirs(path_to_CSV+"CSV/"+date)
|
||||
|
||||
fill_percent_file = str(round(data['Fillage_Percent'],3)).replace(".","-")
|
||||
rename_file = path_to_CSV+"CSV/"+ date+"/"+st+"_"+str(data["Card_ID"])+"_"+data['Card_Type']+ "_"+fill_percent_file +".csv"
|
||||
os.rename(filename, rename_file)
|
||||
|
||||
c.write_tag('Card_Past[1].Data_Read', 1, 'REAL')
|
||||
print "CARD NUMBER " + str(cards_read) + " READ: "+str(data["Card_ID"])+ ", STORED AS "+ rename_file
|
||||
cards_read = cards_read + 1
|
||||
|
||||
|
||||
##############
|
||||
# TAPER DATA #
|
||||
##############
|
||||
update_taper = c.read_tag(["Write_Tapers"])[0][1]
|
||||
if (update_taper == 0):
|
||||
if read_tapers:
|
||||
read_tapers = False
|
||||
print "Update Tapers = False"
|
||||
|
||||
if (update_taper and (not read_tapers) and (update_taper != 911)):
|
||||
print "reading taper file"
|
||||
taper_count = 0;
|
||||
|
||||
tFilename = path_to_CSV + "CSV/TAPER/TAPER_" + datetime.strftime(now,"%Y%m%d_%H%M%S")+ '.CSV'
|
||||
tFile = open(tFilename, 'wb')
|
||||
twr = csv.writer(tFile, quoting=csv.QUOTE_ALL)
|
||||
for taps in range(1,10):
|
||||
taper_in_use_temp = c.read_tag(['Taper.Taper[' + str(taps)+'].Calculated.InUse'])[0][1]
|
||||
if taper_in_use_temp:
|
||||
taper_count = taper_count + 1
|
||||
#print "reading Taper"+ str(taper_count)
|
||||
twr.writerow(["Taper",taper_count])
|
||||
twr.writerow(['Length',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Length'])[0][1]])
|
||||
twr.writerow(['Diameter',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Diameter'])[0][1]])
|
||||
tMaterial = c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Material'])[0][1]
|
||||
if (tMaterial == 1):
|
||||
twr.writerow(['Material',"Steel"])
|
||||
elif (tMaterial == 2):
|
||||
twr.writerow(['Material',"Fiberglass"])
|
||||
twr.writerow(['Weight_Per_Foot', c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Weight'])[0][1]])
|
||||
twr.writerow(['Youngs_Modulus',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Youngs_Modulus'])[0][1]])
|
||||
twr.writerow(['Damping_Factor',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.c'])[0][1]])
|
||||
twr.writerow(['Area',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Area'])[0][1]])
|
||||
twr.writerow(['Rod_Depth',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Rod_Depth'])[0][1]])
|
||||
twr.writerow(['Pressure',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Pressure'])[0][1]])
|
||||
twr.writerow(['Buoyant_Force',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Buoyant_Force'])[0][1]])
|
||||
twr.writerow(['Rod_Weight',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Rod_Weight_Air'])[0][1]])
|
||||
twr.writerow(['Force',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Force'])[0][1]])
|
||||
twr.writerow(['Stretch',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Stretch'])[0][1]])
|
||||
twr.writerow(["",""])
|
||||
else:
|
||||
break
|
||||
twr.writerow(["UnitConfig",""])
|
||||
twr.writerow(['Pump_Diameter',c.read_tag(['UnitConfig.Pump_Diameter'])[0][1]])
|
||||
tFile.close()
|
||||
read_tapers = True
|
||||
print "TAPER DATA READ: "+ tFilename
|
||||
|
||||
##################
|
||||
# GAUGE OFF DATA #
|
||||
##################
|
||||
gauge_off = c.read_tag(['Gauge_Off_Command'])[0][1]
|
||||
if (gauge_off == 0):
|
||||
if already_gauged_off:
|
||||
already_gauged_off = False
|
||||
print "Already gauged off... Setting gauge_off to False"
|
||||
|
||||
if (gauge_off and (not already_gauged_off)):
|
||||
print "Gauging off..."
|
||||
gYear = c.read_tag(['GAUGEOFF_DateTime.Year'])[0][1]
|
||||
gMonth = c.read_tag(['GAUGEOFF_DateTime.Month'])[0][1]
|
||||
gDay = c.read_tag(['GAUGEOFF_DateTime.Day'])[0][1]
|
||||
gHour = c.read_tag(['GAUGEOFF_DateTime.Hour'])[0][1]
|
||||
gMin = c.read_tag(['GAUGEOFF_DateTime.Min'])[0][1]
|
||||
gSec = c.read_tag(['GAUGEOFF_DateTime.Sec'])[0][1]
|
||||
gauge_date = datetime(year = gYear, month = gMonth,day = gDay,hour = gHour,minute = gMin,second = gSec)
|
||||
percent_run = round(c.read_tag(['GAUGEOFF_Percent_Run'])[0][1],2)
|
||||
kWh = round(c.read_tag(['GAUGEOFF_kWh'])[0][1],3)
|
||||
electricity_cost = round(c.read_tag(['GAUGEOFF_Electricity_Cost'])[0][1],2)
|
||||
peak_load = round(c.read_tag(['GAUGEOFF_Max_Load'])[0][1],3)
|
||||
min_load = round(c.read_tag(['GAUGEOFF_Min_Load'])[0][1],3)
|
||||
average_SPM = round(c.read_tag(['GAUGEOFF_Average_SPM'])[0][0],4)
|
||||
production_calculated = round(c.read_tag(['GAUGEOFF_Production_Calculated'])[0][1],2)
|
||||
full_card_production = round(c.read_tag(['GAUGEOFF_Full_Card_Production'])[0][1],2)
|
||||
polished_rod_HP = round(c.read_tag(['GAUGEOFF_Polished_Rod_HP'])[0][1],3)
|
||||
lifting_cost = round(c.read_tag(['GAUGEOFF_Lifting_Cost'])[0][1],4)
|
||||
fluid_above_pump = round(c.read_tag(['GAUGEOFF_Fluid_Above_Pump'])[0][1],2)
|
||||
pump_intake_pressure = round(c.read_tag(['GAUGEOFF_pump_intake_pressure'])[0][1],2)
|
||||
kWh_regen = round(c.read_tag(['GAUGEOFF_kWh_regen'])[0][1],2)
|
||||
inflow_rate = round(c.read_tag(['GAUGEOFF_Inflow_Rate'])[0][1],4)
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
print """INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate)
|
||||
storeHist = cur.execute("""INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate))
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_gauged_off = True
|
||||
print "Gauged off!"
|
||||
|
||||
|
||||
# ##################
|
||||
# # WELL TEST DATA #
|
||||
# ##################
|
||||
|
||||
well_test_entered = c.read_tag(['Well_Test.Test_Submit'])[0][1]
|
||||
if (well_test_entered == 0):
|
||||
if already_entered_well_test:
|
||||
already_entered_well_test = False
|
||||
print "Already entered well Test... Setting well_test_entered to False"
|
||||
if (well_test_entered and (not already_entered_well_test) and well_test_entered != 911):
|
||||
print "Well Test Entered"
|
||||
|
||||
tYear = c.read_tag(['Well_Test.DateTime_Complete.Year'])[0][1]
|
||||
tMonth = c.read_tag(['Well_Test.DateTime_Complete.Month'])[0][1]
|
||||
tDay = c.read_tag(['Well_Test.DateTime_Complete.Day'])[0][1]
|
||||
tHour = c.read_tag(['Well_Test.DateTime_Complete.Hour'])[0][1]
|
||||
tMin = c.read_tag(['Well_Test.DateTime_Complete.Min'])[0][1]
|
||||
tSec = c.read_tag(['Well_Test.DateTime_Complete.Sec'])[0][1]
|
||||
test_date = datetime(year = tYear, month = tMonth,day = tDay,hour = tHour,minute = tMin,second = tSec)
|
||||
test_duration = round(c.read_tag(['Well_Test.Test_Duration'])[0][1],3)
|
||||
v_water = round(c.read_tag(['Well_Test.Volume_Water'])[0][1],3)
|
||||
v_oil = round(c.read_tag(['Well_Test.Volume_Oil'])[0][1],3)
|
||||
v_gas = round(c.read_tag(['Well_Test.Volume_Gas'])[0][1],3)
|
||||
p_v_water = round(c.read_tag(['Well_Test.Projected_Volume_Water'])[0][1],3)
|
||||
p_v_oil = round(c.read_tag(['Well_Test.Projected_Volume_Oil'])[0][1],3)
|
||||
k_factor = round(c.read_tag(['Well_Test.k_Factor'])[0][1],3)
|
||||
api_oil = round(c.read_tag(['Well_Test.API_Oil'])[0][1],3)
|
||||
sg_water = round(c.read_tag(['Well_Test.SG_Water'])[0][1],3)
|
||||
|
||||
db = MySQLdb.connect(host="localhost",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
test_query = "INSERT INTO WellData.Well_Test (test_date, test_volume_oil, test_volume_water, test_volume_gas, k_factor, projected_volume_oil, projected_volume_water, api_gravity_oil, sg_water, test_hours) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}');".format(test_date, v_oil, v_water, v_gas, k_factor, p_v_oil, p_v_water, api_oil, sg_water, test_duration)
|
||||
print test_query
|
||||
storeTest = cur.execute(test_query)
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
already_entered_well_test = True
|
||||
print "Well Test Stored!"
|
||||
|
||||
sleep(.20)
|
||||
66
getTodaysTotals.py
Normal file
66
getTodaysTotals.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
import time
|
||||
import MySQLdb
|
||||
|
||||
def main():
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
try:
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
except:
|
||||
print("PLC Address not set in database... using default of 192.168.1.10")
|
||||
PLC_IP_ADDRESS = "192.168.1.10"
|
||||
PLC_TYPE = "VFD"
|
||||
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
|
||||
today_tags = [
|
||||
{'name':"Average_SPM",'tag':"TODAY_Average_SPM"},
|
||||
{'name':"Downhole_Net_Stroke",'tag':"TODAY_Downhole_NetStroke"},
|
||||
{'name':"Electricity_Cost",'tag':"TODAY_Electricity_Cost"},
|
||||
{'name':"Fluid_Level",'tag':"TODAY_Fluid_Above_Pump"},
|
||||
{'name':"Full_Card_Production",'tag':"TODAY_Full_Card_Production"},
|
||||
{'name':"Inflow_Rate",'tag':"TODAY_Inflow_Rate"},
|
||||
{'name':"kWh",'tag':"TODAY_kWh"},
|
||||
{'name':"kWh_Regen",'tag':"TODAY_kWh_Regen"},
|
||||
{'name':"Lifting_Cost",'tag':"TODAY_Lifting_Cost"},
|
||||
{'name':"Peak_Load",'tag':"TODAY_Max_Load"},
|
||||
{'name':"Min_Load",'tag':"TODAY_Min_Load"},
|
||||
{'name':"Percent_Run",'tag':"TODAY_Percent_Run"},
|
||||
{'name':"Polished_Rod_HP",'tag':"TODAY_Polished_Rod_HP"},
|
||||
{'name':"Calculated_Production",'tag':"TODAY_Production_Calculated"},
|
||||
{'name':"Projected_Production",'tag':"TODAY_Production_Projected"},
|
||||
{'name':"Pump_HP",'tag':"TODAY_Pump_HP"},
|
||||
{'name':"Pump_Intake_Presure",'tag':"TODAY_Pump_Intake_Pressure"},
|
||||
{'name':"Surface_Stroke_Length",'tag':"TODAY_Surface_StrokeLength"},
|
||||
{'name':"Tubing_Movement",'tag':"TODAY_Tubing_Movement"}
|
||||
]
|
||||
|
||||
out_tags = {}
|
||||
try:
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
out_list = map(lambda i: {'name':i['name'], 'value':c.read_tag([i['tag']])[0][1]}, today_tags)
|
||||
return {'status':'success', 'values':out_list}
|
||||
# for i in today_tags:
|
||||
# out_tags[i['name']] = c.read_tag([i['tag']])[0][1]
|
||||
# return out_tags
|
||||
|
||||
|
||||
except Exception, e:
|
||||
# print("FATAL ERROR: Communication Error connecting to the PLC... ", e)
|
||||
return {'status':'error', 'message':e}
|
||||
|
||||
if __name__ == '__main__':
|
||||
print main()
|
||||
44
readTag.py
Normal file
44
readTag.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import MySQLdb
|
||||
|
||||
def main(tagName):
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
|
||||
#PYCOMM Connection to PLC
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
|
||||
def readString(tag):
|
||||
read_vals = c.read_array(tag, 82)
|
||||
string = filter(lambda b: b != "",map(lambda a: chr(a[1]),read_vals))
|
||||
return "".join(string)
|
||||
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
out = {}
|
||||
try:
|
||||
result = c.read_tag([tagName])
|
||||
if result[0][2] == None:
|
||||
raise ValueError('Tag not found')
|
||||
out['status'] = "success"
|
||||
out['value'] = result[0][1]
|
||||
out['type'] = result[0][2]
|
||||
except Exception, e:
|
||||
out['status'] = "error"
|
||||
out['message'] = "Tag not found"
|
||||
return out
|
||||
|
||||
if __name__ == '__main__':
|
||||
res = main(sys.argv[1])
|
||||
print res
|
||||
117
restorePLC.py
Normal file
117
restorePLC.py
Normal file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created on Oct 1, 2014
|
||||
|
||||
@author: PJMcdona
|
||||
'''
|
||||
|
||||
|
||||
#from prettytable import PrettyTable
|
||||
import csv
|
||||
from datetime import datetime
|
||||
import os
|
||||
import sys
|
||||
from random import randint
|
||||
from time import sleep
|
||||
import MySQLdb
|
||||
|
||||
def main(fullfilepath):
|
||||
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
PLC_IP_ADDRESS = setup[0][2]
|
||||
PLC_TYPE = setup[0][1]
|
||||
|
||||
|
||||
|
||||
#TUXEIP Connection to PLC
|
||||
from tuxeip import TuxEIP, LGX, LGX_REAL, LGX_BOOL, LGX_INT, LGX_DINT, LGX_SINT
|
||||
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')
|
||||
|
||||
def WriteToPLC(tag, ttype, value):
|
||||
try:
|
||||
r=0
|
||||
if ttype == "INT":
|
||||
r = tux.WriteLGXData(sess, conn, tag, LGX_INT, int(value), 1)
|
||||
elif ttype == "DINT":
|
||||
r = tux.WriteLGXData(sess, conn, tag, LGX_DINT, int(value), 1)
|
||||
elif ttype == "SINT":
|
||||
r = tux.WriteLGXData(sess, conn, tag, LGX_SINT, int(value), 1)
|
||||
elif ttype == "REAL":
|
||||
r = tux.WriteLGXData(sess, conn, tag, LGX_REAL, float(value), 1)
|
||||
elif ttype == "BOOL":
|
||||
r = tux.WriteLGXData(sess, conn, tag, LGX_BOOL, int(value), 1)
|
||||
else:
|
||||
print "invalid type", ttype
|
||||
r = -1
|
||||
if r == -1:
|
||||
print "Error writing to", tag
|
||||
except:
|
||||
print "Error writing to", tag
|
||||
|
||||
def ReadFromPLC(tag, tag_type):
|
||||
try:
|
||||
if (tag_type == "REAL"):
|
||||
a = tux.ReadLGXDataAsFloat(sess, conn, tag, 1)
|
||||
result = round(float(a[0]),3)
|
||||
#elif (tag_type == "INT" or tag_type == "DINT" or tag_type =="SINT"):
|
||||
elif tag_type[-3:] == "INT":
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
result = int(a[0])
|
||||
elif (tag_type == "BOOL"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 1)
|
||||
intermediate = int(a[0])
|
||||
if intermediate == 0:
|
||||
result = 0
|
||||
else:
|
||||
result = 1
|
||||
elif (tag_type =="STRING"):
|
||||
a = tux.ReadLGXDataAsInteger(sess, conn, tag, 82)
|
||||
word = ""
|
||||
for ch in range(len(a)):
|
||||
word = word + unichr(int(a[ch]))
|
||||
result = word
|
||||
else:
|
||||
result = "?"
|
||||
return result
|
||||
except:
|
||||
print "Unable to read " + tag
|
||||
return 911
|
||||
|
||||
errors = []
|
||||
myfile = open(fullfilepath, 'rb')
|
||||
wr = csv.reader(myfile)
|
||||
for row in wr:
|
||||
if len(row) == 3:
|
||||
(tag, value, tagType) = row
|
||||
WriteToPLC(tag, tagType, value)
|
||||
actual = ReadFromPLC(tag, tagType)
|
||||
verify = False
|
||||
if tagType == "REAL":
|
||||
verify = actual == float(value)
|
||||
elif tagType[-3:] == "INT":
|
||||
verify = actual == int(value)
|
||||
elif tagType == "BOOL":
|
||||
verify = actual == int(value)
|
||||
if not verify:
|
||||
errors.append( "Validation Error:", tag, "does not equal", value, "(actual value:", actual,")")
|
||||
myfile.close()
|
||||
print "Restore Complete with", len(errors), "errors."
|
||||
if len(errors) > 0:
|
||||
print "-------------------------"
|
||||
print "-- ERRORS --"
|
||||
print "-------------------------"
|
||||
for i in range(0,len(errors)):
|
||||
print i+1,"-",errors[i]
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1])
|
||||
276
tuxeip.py
Normal file
276
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_)
|
||||
120
writeTag.py
Normal file
120
writeTag.py
Normal file
@@ -0,0 +1,120 @@
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
import sys
|
||||
import MySQLdb
|
||||
from time import sleep
|
||||
|
||||
def closeEnough(a,b):
|
||||
return abs(a - b) <= 0.1
|
||||
|
||||
def getPLCIP():
|
||||
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
|
||||
cur = db.cursor()
|
||||
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
|
||||
cur.execute(query)
|
||||
setup = cur.fetchall()
|
||||
db.commit()
|
||||
db.close()
|
||||
|
||||
return setup[0][2]
|
||||
|
||||
def readTag(tagName):
|
||||
PLC_IP_ADDRESS = getPLCIP()
|
||||
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
|
||||
def readString(tag):
|
||||
read_vals = c.read_array(tag, 82)
|
||||
string = filter(lambda b: b != "",map(lambda a: chr(a[1]),read_vals))
|
||||
return "".join(string)
|
||||
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
out = {}
|
||||
try:
|
||||
result = c.read_tag([tagName])
|
||||
if result[0][2] == None:
|
||||
raise ValueError('Tag not found')
|
||||
out['status'] = "success"
|
||||
out['value'] = result[0][1]
|
||||
out['type'] = result[0][2]
|
||||
except Exception, e:
|
||||
out['status'] = "error"
|
||||
out['message'] = "Tag Not Found"
|
||||
c.close()
|
||||
return out
|
||||
|
||||
def main(tag, value):
|
||||
|
||||
r = 0
|
||||
PLC_IP_ADDRESS = getPLCIP()
|
||||
|
||||
readObj = readTag(tag)
|
||||
if readObj['status'] == "error":
|
||||
return readObj
|
||||
elif readObj['status'] == 'success':
|
||||
tagType = readObj['type']
|
||||
|
||||
if tagType[:-3] == "INT" or tagType == "BOOL":
|
||||
value = int(value)
|
||||
elif tagType == "REAL":
|
||||
value = float(value)
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
r = c.write_tag(tag, value, tagType)
|
||||
else:
|
||||
return {"status": 'error', "message": "not connected to PLC"}
|
||||
c.close()
|
||||
|
||||
sleep(2)
|
||||
|
||||
return readTag(tag)
|
||||
|
||||
def writeTagAndVerify(tag,value, sleepValue=2):
|
||||
"""Writes the specified value to tag and confirms that the value has been set"""
|
||||
r = 0
|
||||
PLC_IP_ADDRESS = getPLCIP()
|
||||
readObj = readTag(tag)
|
||||
if readObj['status'] == "error":
|
||||
return readObj
|
||||
elif readObj['status'] == 'success':
|
||||
tagType = readObj['type']
|
||||
prevValue = readObj['value']
|
||||
if tagType[:-3] == "INT" or tagType == "BOOL":
|
||||
value = int(value)
|
||||
elif tagType == "REAL":
|
||||
value = float(value)
|
||||
c = ClxDriver(True, 'ClxDriver.log')
|
||||
if c.open(PLC_IP_ADDRESS):
|
||||
r = c.write_tag(tag, value, tagType)
|
||||
sleep(float(sleepValue))
|
||||
newObj = readTag(tag)
|
||||
if newObj['status'] == "error":
|
||||
return newObj
|
||||
elif newObj['status'] == 'success':
|
||||
newTagType = newObj['type']
|
||||
newValue = newObj['value']
|
||||
if (newTagType == tagType):
|
||||
if (closeEnough(newValue, value)):
|
||||
return {'status':'success', 'value':newValue, 'type':newTagType, 'verified':'true','prevValue':prevValue}
|
||||
else:
|
||||
return {"status": 'error', "message": "The tag value does not match the specified value", "value":newValue}
|
||||
else:
|
||||
return {"status": 'error', "message": "Somehow the tag type has changed"}
|
||||
else:
|
||||
return {"status": 'error', "message": "not connected to PLC"}
|
||||
c.close()
|
||||
|
||||
def toggle(tag, toggleVal, timeToggled=2):
|
||||
val = int(toggleVal)
|
||||
set_tag = writeTagAndVerify(tag,toggleVal,sleepValue=1)
|
||||
if set_tag['status']== 'success':
|
||||
sleep(timeToggled)
|
||||
reset_tag = writeTagAndVerify(tag, set_tag['prevValue'],sleepValue=1)
|
||||
if reset_tag['status'] == "success":
|
||||
return {'status':'success'}
|
||||
else:
|
||||
return {'status':'error', 'message':reset_tag['message']}
|
||||
else:
|
||||
return {'status':'error', 'message':set_tag['message']}
|
||||
|
||||
if __name__ == '__main__':
|
||||
print main(sys.argv[1], sys.argv[2])
|
||||
Reference in New Issue
Block a user