set up ability to switch back and forth between MySQL and SQLite

This commit is contained in:
Patrick McDonagh
2016-04-20 15:14:58 -05:00
parent 1a4c6730f9
commit 3e2253d387
21 changed files with 675 additions and 2095 deletions

13
README.md Normal file
View File

@@ -0,0 +1,13 @@
# POConsole Data Acquisition and Storage Platform
By Henry Pump
## Installation
1. Clone this repo
2. Make either setdb_MySQL.sh or setdb_SQLite.sh executable
3. Run setdb_MySQL.sh or setdb_SQLite.sh
## Credits
Developed by Patrick McDonagh, Henry Pump
pmcdonagh@henry-pump.com

View File

@@ -1,44 +1,33 @@
#!/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
import time
from readConfig import readConfig
from pycomm.ab_comm.clx import Driver as ClxDriver
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]
configProperties = readConfig()
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')
def readTag(addr, tag):
time.sleep(0.01)
c = ClxDriver()
if c.open(addr):
try:
v = c.read_tag(tag)
# print(v)
return v
except Exception:
print("ERROR RETRIEVING TAG: {}".format(tag))
c.close()
print traceback.print_exc()
pass
c.close()
now = datetime.now()
nowDT = datetime.strftime(now,"%Y%m%d_%H%M%S")
@@ -93,46 +82,13 @@ tags_to_read = [['Casing_ID', '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()
with open(filename, 'wb') as myfile:
wr = csv.writer(myfile)
for t in tags_to_read:
tagVal = readTag(configProperties['PLC_IP_ADDRESS'], t[0])[0]
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], readTag(configProperties['PLC_IP_ADDRESS'], "Taper.Taper[" + str(i) + "].Setup." + p[0])[0], p[1]])
print "Backed up PLC settings to", filename

View File

@@ -1,92 +0,0 @@
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()

View File

@@ -1,376 +0,0 @@
#!/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)

View File

@@ -1,422 +0,0 @@
#!/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 checkDateInDB(da):
y = int(da[0:4])
m = int(da[4:6])
d = int(da[6:8])
dquery = "SELECT id FROM WellData.card_history_dates WHERE year = {0} AND month = {1} AND day = {2};".format(y, m, d)
# dquery = "SELECT id FROM WellData.card_history_dates WHERE year = 2016 AND month = 1 AND day = 5;"
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
cur = db.cursor()
cur.execute(dquery)
dates = cur.fetchall()
# db.commit()
db.close()
if len(dates) > 0:
print("Date {0} already in db".format(da))
else:
ins_query = "INSERT INTO WellData.card_history_dates (year, month, day, first_id) VALUES ({0}, {1}, {2}, (SELECT MAX(id) FROM WellData.card_history));".format(y, m, d)
print(ins_query)
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
cur = db.cursor()
cur.execute(ins_query)
db.commit()
db.close()
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
last_date = ""
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 not date == last_date:
checkDateInDB(date)
last_date = date
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)

View File

@@ -1,577 +0,0 @@
#!/usr/bin/env python
'''
Created on Oct 1, 2014
@author: PJMcdona
'''
# import csv
from datetime import datetime
import time
import sqlite3 as lite
from pycomm.ab_comm.clx import Driver as ClxDriver
# import logging
import traceback
con = lite.connect("/mnt/usb/data.db")
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
def readConfig():
global PLC_IP_ADDRESS, PLC_TYPE
with con:
cur = con.cursor()
query = "SELECT * FROM config ORDER BY dateChanged DESC LIMIT 1;"
cur.execute(query)
setup = cur.fetchall()
PLC_IP_ADDRESS = setup[0][2]
PLC_TYPE = setup[0][1]
def readTag(addr, tag):
# logging.basicConfig(
# filename="clx.log",
# format="%(levelname)-10s %(asctime)s %(message)s",
# level=logging.DEBUG
# )
c = ClxDriver()
if c.open(addr):
try:
v = c.read_tag(tag)
# print(v)
return v
except Exception:
print("ERROR RETRIEVING TAG: {}".format(tag))
err = c.get_status()
c.close()
print err
pass
c.close()
def readArray(addr, arr, length):
# logging.basicConfig(filename="clx.log", format="%(levelname)-10s %(asctime)s %(message)s", level=logging.DEBUG)
c = ClxDriver()
if c.open(addr):
try:
v = c.read_array(arr, length)
# print(v)
return map(lambda x: x[1], v)
except Exception:
print("ERROR RETRIEVING ARRAY: {}".format(arr))
err = c.get_status()
c.close()
print err
pass
c.close()
def checkDateInDB(da):
y = int(da[0:4])
m = int(da[4:6])
d = int(da[6:8])
dquery = "SELECT id FROM card_history_dates WHERE year = {0} AND month = {1} AND day = {2};".format(y, m, d)
# dquery = "SELECT id FROM WellData.card_history_dates WHERE year = 2016 AND month = 1 AND day = 5;"
with con:
cur = con.cursor()
cur.execute(dquery)
dates = cur.fetchall()
if len(dates) > 0:
print("Date {0} already in db".format(da))
else:
ins_query = "INSERT INTO card_history_dates (year, month, day, first_id) VALUES ({0}, {1}, {2}, (SELECT MAX(id) FROM card_history));".format(y, m, d)
print(ins_query)
with con:
cur = con.cursor()
cur.execute(ins_query)
con.commit()
class Tag():
global readTag, con
def __init__(self, name, tag, data_type, change_threshold, guarantee_sec, mapFn=None):
self.name = name
self.tag = tag
self.data_type = data_type
self.value = None
self.last_value = None
self.guarantee_sec = guarantee_sec
self.chg_threshold = change_threshold
self.last_send_time = 0
self.mapFn = mapFn
def read(self, forceSend):
if self.tag:
v = readTag(PLC_IP_ADDRESS, self.tag)
if v:
if self.data_type == 'BOOL' or self.data_type == 'STRING':
val = v[0]
if self.mapFn:
val = self.mapFn[val]
if (self.last_send_time == 0) or (self.value is None) or not (self.value == val) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend):
self.last_value = self.value
self.value = val
return True
else:
return False
else:
if (self.last_send_time == 0) or (self.value is None) or (abs(self.value - v[0]) > self.chg_threshold) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend):
self.last_value = self.value
self.value = v[0]
return True
else:
return False
else:
return False
return False
def sendToDB(self):
query = "INSERT INTO tag_vals (dtime, name, val) VALUES ({}, '{}', {})".format(time.time(), self.name, self.value)
print query
with con:
cur = con.cursor()
cur.execute(query)
con.commit()
class Status(Tag):
def sendToDB(self):
query = "INSERT INTO run_status (dtime, status) VALUES ({}, '{}')".format(time.time(), self.value)
print query
with con:
cur = con.cursor()
cur.execute(query)
con.commit()
self.last_send_time = time.time()
class AnalogAlarm():
def __init__(self, name, tag):
self.name = name
self.tag = tag
self.alarm = False
self.warning = False
self.lastAlarmCheckVal = False
self.lastWarningCheckVal = False
def checkStatus(self, stroke_number):
global readTag, PLC_IP_ADDRESS, conditionMap, con
condition = ''
self.alarm = readTag(PLC_IP_ADDRESS, '{}.Alarm'.format(self.tag))[0] > 0
alarmChanged = not (self.alarm == self.lastAlarmCheckVal)
self.warning = readTag(PLC_IP_ADDRESS, '{}.Warning'.format(self.tag))[0] > 0
warningChanged = not (self.warning == self.lastWarningCheckVal)
if (alarmChanged and self.alarm) or (warningChanged and self.warning):
condition = conditionMap[readTag(PLC_IP_ADDRESS, '{}.Alarm_Code'.format(self.tag))[0]]
value = readTag(PLC_IP_ADDRESS, '{}.Alarm_Value'.format(self.tag))[0]
triggerType = "Alarm"
if warningChanged:
triggerType = 'Warning'
iQuery = "INSERT INTO Event_List (device_name, type, cond, value, datetime, tag, stroke_number) VALUES ('{0}', '{1}', '{2}', {3}, '{4}', '{5}', {6});".format(
self.name, triggerType, condition, value, time.time(), self.tag, stroke_number)
print iQuery
with con:
cur = con.cursor()
cur.execute(iQuery)
con.commit()
if warningChanged:
self.lastWarningCheckVal = self.warning
if alarmChanged:
self.lastAlarmCheckVal = self.alarm
class bitAlarm():
def __init__(self, name, tag, condition):
self.name = name
self.tag = tag
self.condition = condition
self.status = False
self.lastStatusCheckVal = False
def checkStatus(self, stroke_number):
global readTag, PLC_IP_ADDRESS, con
self.status = readTag(PLC_IP_ADDRESS, self.tag)[0] > 0
statusChanged = not (self.status == self.lastStatusCheckVal)
if statusChanged and self.status:
value = readTag(PLC_IP_ADDRESS, '{}.Alarm_Value'.format(self.tag))[0]
iQuery = "INSERT INTO Event_List (device_name, type, cond, value, datetime, tag, stroke_number) VALUES ('{0}', '{1}', '{2}', {3}, '{4}', '{5}', {6});".format(
self.name, 'Info', self.condition, 0.0, time.time(), self.tag, stroke_number)
print iQuery
with con:
cur = con.cursor()
cur.execute(iQuery)
con.commit()
if statusChanged:
self.lastStatusCheckVal = self.status
# ---------- MAP FUNCTIONS ---------- #
modeMap = {
0: "Error",
1: "Auto",
2: "POC",
3: "Timer",
4: "Manual",
5: "DH PID"
}
card_type_map = {
0: "Normal",
1: "Shutdown",
2: "Alarm",
3: "Startup",
4: "Low Fillage"
}
statusMap = {
0: 'Stopped',
1: 'Running',
2: 'Pumped Off',
3: 'Faulted',
4: 'Starting',
5: 'Recovering',
100: 'Read Error',
1000: 'PLC Error',
9999: 'No Response'
}
conditionMap = {
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"
}
# ---------- TAGS ---------- #
stroke_tags = {
'card_id': Tag('card_id', 'Card_Past[1].ID', 'DINT', 25, 3600),
'card_type': Tag('card_type', 'Card_Past[1].Card_Type', 'STRING', 0, 3600, mapFn=card_type_map)
}
status = Status('run_status', 'Pump.Run_Status', 'STRING', 0, 3600, mapFn=statusMap)
history_tags = {
'torque_reference': Tag('torque_reference', 'PF755_Drive:O.TrqRefAStpt', 'REAL', 1.0, 3600),
'speed_reference': Tag('speed_reference', 'Pump_PF755.PSet_SpeedRef', 'REAL', 10.0, 3600),
'downhole_adjusted_gross_stroke': Tag('downhole_adjusted_gross_stroke', 'Card_Past[1].Downhole_AdjustedGrossStroke', 'REAL', 2.0, 3600),
'downhole_fluid_load': Tag('downhole_fluid_load', 'Card_Past[1].Downhole_FluidLoad', 'REAL', 400.0, 3600),
'downhole_gross_stroke': Tag('downhole_gross_stroke', 'Card_Past[1].Downhole_GrossStroke', 'REAL', 2.0, 3600),
'downhole_max_load': Tag('downhole_max_load', 'Card_Past[1].Downhole_Max_Load.Load', 'REAL', 400.0, 3600),
'downhole_max_position': Tag('downhole_max_position', 'Card_Past[1].Downhole_Max_Position.Position', 'REAL', 2.0, 3600),
'downhole_min_load': Tag('downhole_min_load', 'Card_Past[1].Downhole_Min_Load.Load', 'REAL', 400.0, 3600),
'downhole_min_position': Tag('downhole_min_position', 'Card_Past[1].Downhole_Min_Position.Position', 'REAL', 2.0, 3600),
'downhole_net_stroke': Tag('downhole_net_stroke', 'Card_Past[1].Downhole_NetStroke', 'REAL', 2.0, 3600),
'drive_torque_mode': Tag('drive_torque_mode', 'DriveTorqueMode', 'BOOL', 1.0, 3600),
'fillage_percent': Tag('fillage_percent', 'Card_Past[1].Fillage_Percent', 'REAL', 5.0, 3600),
'fluid_gradient': Tag('fluid_gradient', 'Card_Past[1].Params.Fluid_Gradient', 'REAL', 0.002, 3600),
'fluid_level': Tag('fluid_level', 'Card_Past[1].Fluid_Above_Pump', 'REAL', 100.0, 3600),
'polished_rod_hp': Tag('polished_rod_hp', 'Card_Past[1].Polished_Rod_HP', 'REAL', 1.0, 3600),
'pump_hp': Tag('pump_hp', 'Card_Past[1].Pump_HP', 'REAL', 1.0, 3600),
'pump_intake_pressure': Tag('pump_intake_pressure', 'Card_Past[1].Pump_Intake_Pressure', 'REAL', 200.0, 3600),
'spm': Tag('spm', 'Card_Past[1].SPM', 'REAL', 0.5, 3600),
'stroke_production': Tag('stroke_production', 'Stroke_Production', 'REAL', 0.005, 3600),
'stuffing_box_friction': Tag('stuffing_box_friction', 'Card_Past[1].Params.Stuffing_Box_Friction', 'REAL', 1.0, 3600),
'surface_max_load': Tag('surface_max_load', 'Card_Past[1].Surface_Max.Load', 'REAL', 400.0, 3600),
'surface_max_position': Tag('surface_max_position', 'Card_Past[1].Surface_Max.Position', 'REAL', 1.0, 3600),
'surface_min_load': Tag('surface_min_load', 'Card_Past[1].Surface_Min.Load', 'REAL', 400.0, 3600),
'surface_min_position': Tag('surface_min_position', 'Card_Past[1].Surface_Min.Position', 'REAL', 1.0, 3600),
'surface_stroke_length': Tag('surface_stroke_length', 'Card_Past[1].Surface_StrokeLength', 'REAL', 1.0, 3600),
'tubing_head_pressure': Tag('tubing_head_pressure', 'Card_Past[1].Params.Tubing_Head_Pressure', 'REAL', 25.0, 3600),
'tubing_movement': Tag('tubing_movement', 'Card_Past[1].Tubing_Movement', 'REAL', 1.0, 3600),
'dt': Tag('dt', 'Card_Past[1].Params.dt', 'REAL', 0.001, 3600),
}
gaugeoff_tags = {
'year': Tag('year', 'GAUGEOFF_DateTime.Year', 'DINT', 0, 0),
'month': Tag('month', 'GAUGEOFF_DateTime.Month', 'DINT', 0, 0),
'day': Tag('day', 'GAUGEOFF_DateTime.Day', 'DINT', 0, 0),
'hour': Tag('hour', 'GAUGEOFF_DateTime.Hour', 'DINT', 0, 0),
'min': Tag('min', 'GAUGEOFF_DateTime.Min', 'DINT', 0, 0),
'sec': Tag('sec', 'GAUGEOFF_DateTime.Sec', 'DINT', 0, 0),
'percent_run': Tag('percent_run', 'GAUGEOFF_Percent_Run', 'REAL', 0, 0),
'kwh': Tag('kwh', 'GAUGEOFF_kWh', 'REAL', 0, 0),
'electricity_cost': Tag('electricity_cost', 'GAUGEOFF_Electricity_Cost', 'REAL', 0, 0),
'max_load': Tag('max_load', 'GAUGEOFF_Max_Load', 'REAL', 0, 0),
'min_load': Tag('min_load', 'GAUGEOFF_Min_Load', 'REAL', 0, 0),
'average_spm': Tag('average_spm', 'GAUGEOFF_Average_SPM', 'REAL', 0, 0),
'production_calculated': Tag('production_calculated', 'GAUGEOFF_Production_Calculated', 'REAL', 0, 0),
'full_card_production': Tag('full_card_production', 'GAUGEOFF_Full_Card_Production', 'REAL', 0, 0),
'polished_rod_hp': Tag('polished_rod_hp', 'GAUGEOFF_Polished_Rod_HP', 'REAL', 0, 0),
'lifting_cost': Tag('lifting_cost', 'GAUGEOFF_Lifting_Cost', 'REAL', 0, 0),
'fluid_level': Tag('fluid_level', 'GAUGEOFF_Fluid_Above_Pump', 'REAL', 0, 0),
'pump_intake_pressure': Tag('pump_intake_pressure', 'GAUGEOFF_pump_intake_pressure', 'REAL', 0, 0),
'kwh_regen': Tag('kwh_regen', 'GAUGEOFF_kWh_regen', 'REAL', 0, 0),
'inflow_rate': Tag('inflow_rate', 'GAUGEOFF_Inflow_Rate', 'REAL', 0, 0)
}
welltest_tags = {
'year': Tag('year', "Well_Test.DateTime_Complete.Year", "INT", 0, 0),
'month': Tag('month', "Well_Test.DateTime_Complete.Month", "INT", 0, 0),
'day': Tag('day', "Well_Test.DateTime_Complete.Day", "INT", 0, 0),
'hour': Tag('hour', "Well_Test.DateTime_Complete.Hour", "INT", 0, 0),
'min': Tag('min', "Well_Test.DateTime_Complete.Min", "INT", 0, 0),
'sec': Tag('sec', "Well_Test.DateTime_Complete.Sec", "INT", 0, 0),
'test_duration': Tag('test_duration', "Well_Test.Test_Duration", "REAL", 0, 0),
'v_water': Tag('v_water', "Well_Test.Volume_Water", "REAL", 0, 0),
'v_oil': Tag('v_oil', "Well_Test.Volume_Oil", "REAL", 0, 0),
'v_gas': Tag('v_gas', "Well_Test.Volume_Gas", "REAL", 0, 0),
'p_v_water': Tag('p_v_water', "Well_Test.Projected_Volume_Water", "REAL", 0, 0),
'p_v_oil': Tag('p_v_oil', "Well_Test.Projected_Volume_Oil", "REAL", 0, 0),
'k_factor': Tag('k_factor', "Well_Test.k_Factor", "REAL", 0, 0),
'api_oil': Tag('api_oil', "Well_Test.API_Oil", "REAL", 0, 0),
'sg_water': Tag('sg_water', "Well_Test.SG_Water", "REAL", 0, 0)
}
# setpoint_tags = {
# 'mode': {'Mode', "Pump.Mode", "INT", 0.5, 3600, mapFn=modeMap},
# 'speed_setpoint_spm': {'Speed_Setpoint_SPM', "Pump.Speed_Setpoint_SPM", "REAL", 0.5, 3600},
# 'speed_max': {'Speed_Max', "Pump.Speed_Max", "REAL", 0.5, 3600},
# 'speed_min': {'Speed_Min', "Pump.Speed_Min", "REAL", 0.5, 3600},
# 'auto_speed_startpoint_spm': {'Auto-Speed_Startpoint_SPM', "Pump.Speed_Startpoint_SPM_Auto", "REAL", 0.5, 3600},
# 'auto_percentage_ramp_down': {'Auto-Percentage_Ramp_Down', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_increment_ramp_down': {'Auto-Increment_Ramp_Down', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_percent_ramp_up': {'Auto-Percent_Ramp_Up', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_percent_ramp_down': {'Auto-Percent_Ramp_Down', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_min_speed_strokes': {'Auto-Min_Speed_Strokes', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_percent_ramp_up': {'Auto-Percent_Ramp_Up', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_poc_startup_ignore_cards': {'Auto-POC-Startup_Ignore_Cards', "Pump.Mode", "REAL", 1.0, 3600},
# 'auto_poc_card_quantity': {'Auto-POC-Card_Quantity', "Pump.Mode", "REAL", 1.0, 3600},
# 'poc_percent_pumpoff': {'POC-Percent_Pumpoff', "Pump.Mode", "REAL", 1.0, 3600}
# }
bit_tags = {
'Pump Off (Auto Mode)': bitAlarm('Pump Off (Auto Mode)', 'Pump.Auto_Stop', 'Unit Stop'),
'Pump Off (POC Mode)': bitAlarm('Pump Off (POC Mode)', 'Pump.POC_Stop', 'Unit Stop'),
'Pump Off (Timer Mode)': bitAlarm('Pump Off (Timer Mode)', 'Pump.Timed_Stop', 'Unit Stop'),
'User Initiated Stop': bitAlarm('User Initiated Stop', 'Pump.Stop', 'Unit Stop'),
'Peak Energy Stop': bitAlarm('Peak Energy Stop', 'PeakEnergy.Stop', 'Unit Stop'),
'User Initiated Start': bitAlarm('User Initiated Start', 'Pump.Start', 'Unit Start'),
'Restart (POC Mode)': bitAlarm('Restart (POC Mode)', 'Pump.POC_Restart', 'Unit Start'),
'Restart (Timer Mode)': bitAlarm('Restart (Timer Mode)', 'Pump.Timed_Restart', 'Unit Start'),
'Restart (Auto Mode)': bitAlarm('Restart (Auto Mode)', 'Pump.Auto_Restart', 'Unit Start'),
'Peak Energy Restart': bitAlarm('Peak Energy Restart', 'PeakEnergy.Restart', 'Unit Start'),
'Unit Jogged': bitAlarm('Unit Jogged', 'Pump.Jog', 'Unit Jog')
}
safety_tags = {
'Casing Pressure': AnalogAlarm('Casing Pressure', 'Safety_Casing_Pressure'),
'Flow Line Pressure': AnalogAlarm('Flow Line Pressure', 'Safety_Flow_Line_Pressure'),
'Flowmeter': AnalogAlarm('Flowmeter', 'Safety_Flowmeter'),
'Fluid Load': AnalogAlarm('Fluid Load', 'Safety_Fluid_Load'),
'Inclinometer': AnalogAlarm('Inclinometer', 'Safety_Inclinometer'),
'Load HiHi': AnalogAlarm('Load HiHi', 'Safety_Load_HiHi'),
'Load Hi': AnalogAlarm('Load Hi', 'Safety_Load_Hi'),
'Load Lo': AnalogAlarm('Load Lo', 'Safety_Load_Lo'),
'Load LoLo': AnalogAlarm('Load LoLo', 'Safety_Load_LoLo'),
'Speed': AnalogAlarm('Speed', 'Safety_Speed'),
'Tubing Pressure': AnalogAlarm('Tubing Pressure', 'Safety_Tubing_Pressure')
}
def readPoints():
global PLC_IP_ADDRESS
num_points = readTag(PLC_IP_ADDRESS, "Card_Past[1].Num_Points")[0]
surf_pos = readArray(PLC_IP_ADDRESS, "Card_Past[1].Surface_Position", num_points + 1)[1:]
surf_pos.append(surf_pos[0])
surf_lod = readArray(PLC_IP_ADDRESS, "Card_Past[1].Surface_Load", num_points + 1)[1:]
surf_lod.append(surf_lod[0])
down_pos = readArray(PLC_IP_ADDRESS, "Card_Past[1].Downhole_Position", num_points + 1)[1:]
down_pos.append(down_pos[0])
down_lod = readArray(PLC_IP_ADDRESS, "Card_Past[1].Downhole_Load", num_points + 1)[1:]
down_lod.append(down_lod[0])
return([surf_pos, surf_lod, down_pos, down_lod])
def evalTapers():
ts = time.time()
numTapers = int(readTag(PLC_IP_ADDRESS, 'Card_Current.Params.Num_Tapers')[0])
for t in range(1, numTapers + 1):
taper_length = readTag(PLC_IP_ADDRESS, 'Taper.Taper[{}].Setup.Length'.format(t))[0]
taper_diameter = readTag(PLC_IP_ADDRESS, 'Taper.Taper[{}].Setup.Diameter'.format(t))[0]
taper_material = readTag(PLC_IP_ADDRESS, 'Taper.Taper[{}].Setup.Material'.format(t))[0]
if (taper_material == 1):
taper_material = "Steel"
elif (taper_material == 2):
taper_material = "Fiberglass"
tStr = "{{'taper':{}, 'length': {}, 'diameter': {}, 'material':'{}'}}".format(t, taper_length, taper_diameter, taper_material)
tQuery = 'INSERT INTO well_config (tstamp, type, val) VALUES ({}, "taper", "{}")'.format(ts, tStr)
print tQuery
with con:
cur = con.cursor()
cur.execute(tQuery)
con.commit()
pump_diameter = readTag(PLC_IP_ADDRESS, 'UnitConfig.Pump_Diameter')[0]
cfgQuery = "INSERT INTO well_config (tstamp, type, val) VALUES ({}, 'pump_diameter', '{}')".format(ts, pump_diameter)
with con:
cur = con.cursor()
cur.execute(cfgQuery)
con.commit()
print "TAPER DATA READ!"
return True
def main():
read_tapers = False
already_gauged_off = False
already_entered_well_test = False
last_date = ""
last_stroke = 0
while True:
try:
if status.read(False):
status.sendToDB()
#############
# CARD DATA #
#############
EOS = readTag(PLC_IP_ADDRESS, "End_Of_Stroke")[0]
stroke_tags['card_id'].read(False)
if (EOS and not (last_stroke == stroke_tags['card_id'].value)):
sData = {}
last_stroke = stroke_tags['card_id'].value
stroke_time = time.time()
dt = datetime.fromtimestamp(stroke_time)
sData['localtime'] = dt
sData['stroke_time'] = dt
sData['utctime'] = datetime.utcfromtimestamp(stroke_time)
for t in stroke_tags:
stroke_tags[t].read(True)
[sData['Surface_Position'], sData['Surface_Load'], sData['Downhole_Position'], sData['Downhole_Load']] = readPoints()
# st = datetime.strftime(dt, "%Y%m%d_%H%M%S")
date = datetime.strftime(dt, "%Y%m%d")
if not date == last_date:
checkDateInDB(date)
last_date = date
sData["card_type"] = stroke_tags['card_type'].value
sData["card_id"] = stroke_tags['card_id'].value
sData['sp_string'] = ', '.join(map(str, sData['Surface_Position']))
sData['sl_string'] = ', '.join(map(str, sData['Surface_Load']))
sData['dp_string'] = ', '.join(map(str, sData['Downhole_Position']))
sData['dl_string'] = ', '.join(map(str, sData['Downhole_Load']))
insert_query = "INSERT INTO card_history (Card_ID, Card_Type, Stroke_Time, Surface_Position, Surface_Load, Downhole_Position, Downhole_Load) VALUES (:card_id, :card_type, :stroke_time, :sp_string, :sl_string, :dp_string, :dl_string)"
with con:
cur = con.cursor()
cur.execute(insert_query, sData)
con.commit()
print "CARD NUMBER " + str(sData["card_id"]) + " READ!"
###################
# HISTORICAL DATA #
###################
for hist in history_tags:
h = history_tags[hist]
if h.read(False):
h.sendToDB()
h.last_send_time = time.time()
##############
# TAPER DATA #
##############
update_taper = readTag(PLC_IP_ADDRESS, "Write_Tapers")[0] > 0
if (update_taper == 0):
if read_tapers:
read_tapers = False
print "Update Tapers = False"
if (update_taper and (not read_tapers)):
print "reading taper file"
read_tapers = evalTapers()
##################
# GAUGE OFF DATA #
##################
gauge_off = readTag(PLC_IP_ADDRESS, "Gauge_Off_Command")[0]
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..."
for goff in gaugeoff_tags:
g = gaugeoff_tags[goff]
g.read(True)
gauge_date = datetime(year=gaugeoff_tags['year'].value, month=gaugeoff_tags['month'].value, day=gaugeoff_tags['day'].value, hour=gaugeoff_tags['hour'].value, minute=gaugeoff_tags['min'].value, second=gaugeoff_tags['sec'].value)
with con:
cur = con.cursor()
con.execute("""INSERT INTO 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, gaugeoff_tags['percent_run'].value, gaugeoff_tags['kwh'].value, gaugeoff_tags['electricity_cost'].value, gaugeoff_tags['max_load'].value, gaugeoff_tags['min_load'].value, gaugeoff_tags['average_spm'].value, gaugeoff_tags['production_calculated'].value, gaugeoff_tags['full_card_production'].value, gaugeoff_tags['polished_rod_hp'].value, gaugeoff_tags['lifting_cost'].value, gaugeoff_tags['fluid_level'].value, gaugeoff_tags['pump_intake_pressure'].value, gaugeoff_tags['kwh_regen'].value, gaugeoff_tags['inflow_rate'].value))
con.commit()
already_gauged_off = True
print "Gauged off!"
##################
# WELL TEST DATA #
##################
well_test_entered = readTag(PLC_IP_ADDRESS, "Well_Test.Test_Submit")[0] > 0
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)):
for wtest in welltest_tags:
w = welltest_tags[wtest]
w.read(True)
print "Well Test Entered"
print('{}/{}/{} {}:{}:{}'.format(welltest_tags['year'].value, welltest_tags['month'].value, welltest_tags['day'].value, welltest_tags['hour'].value, welltest_tags['min'].value, welltest_tags['sec'].value))
test_date = datetime(year=welltest_tags['year'].value, month=welltest_tags['month'].value, day=welltest_tags['day'].value, hour=welltest_tags['hour'].value, minute=welltest_tags['min'].value, second=welltest_tags['sec'].value)
with con:
cur = con.cursor()
test_query = "INSERT INTO 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, welltest_tags['v_oil'].value, welltest_tags['v_water'].value, welltest_tags['v_gas'].value, welltest_tags['k_factor'].value, welltest_tags['p_v_oil'].value, welltest_tags['p_v_water'].value, welltest_tags['api_oil'].value, welltest_tags['sg_water'].value, welltest_tags['test_duration'].value)
# print test_query
con.execute(test_query)
con.commit()
already_entered_well_test = True
print "Well Test Stored!"
###################
# ALARMS & EVENTS #
###################
for t in safety_tags:
safety_tags[t].checkStatus(stroke_tags['card_id'].value)
for b in bit_tags:
bit_tags[b].checkStatus(stroke_tags['card_id'].value)
time.sleep(.20)
except Exception, e:
print("Error during loop: {}".format(e))
traceback.print_exc()
if __name__ == '__main__':
main()

View File

@@ -1,297 +0,0 @@
#!/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)

View File

@@ -185,6 +185,16 @@ CREATE TABLE IF NOT EXISTS poconsole.alarms(
PRIMARY KEY (id)
);
INSERT INTO tag_classes (id, tag_class, description) VALUES (1, 'stroke', 'Stroke Information');
INSERT INTO tag_classes (id, tag_class, description) VALUES (2, 'history', 'Historical Data');
INSERT INTO tag_classes (id, tag_class, description) VALUES (3, 'gaugeoff', 'Gauge Off Data');
INSERT INTO tag_classes (id, tag_class, description) VALUES (4, 'welltest', 'Well Test Data');
INSERT INTO tag_classes (id, tag_class, description) VALUES (5, 'custom', 'Custom tags');
INSERT INTO alarm_classes(id, alarm_class, description) VALUES (1, 'analog', 'Analog Alarms');
INSERT INTO alarm_classes(id, alarm_class, description) VALUES (2, 'bit', 'Bit Statuses');
CREATE USER 'website'@'localhost' IDENTIFIED BY 'henrypump';
GRANT ALL ON *.* TO 'website'@'localhost';
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'henrypump';

417
dbMySQL/dataLogger_MySQL.py Normal file
View File

@@ -0,0 +1,417 @@
#!/usr/bin/env python
from datetime import datetime
import time
import mysql.connector as mysqlcon
from pycomm.ab_comm.clx import Driver as ClxDriver
from tag.tag_mysql import Tag
from tag.tag_mysql import AnalogAlarm
from tag.tag_mysql import bitAlarm
from readConfig_MySQL import readConfig
import traceback
import pickle
import os
with open(os.path.realpath('.') + '/mysql_cfg.pickle', 'rb') as cfgFile:
mysql_cfg = pickle.load(cfgFile)
con = mysqlcon.connect(**mysql_cfg)
try:
configProperties = readConfig()
except:
traceback.print_exc()
def readTag(addr, tag):
time.sleep(0.01)
c = ClxDriver()
if c.open(addr):
try:
v = c.read_tag(tag)
# print(v)
return v
except Exception:
print("ERROR RETRIEVING TAG: {}".format(tag))
c.close()
print traceback.print_exc()
pass
c.close()
def readArray(addr, arr, length):
# logging.basicConfig(filename="clx.log", format="%(levelname)-10s %(asctime)s %(message)s", level=logging.DEBUG)
c = ClxDriver()
if c.open(addr):
try:
v = c.read_array(arr, length)
# print(v)
return map(lambda x: x[1], v)
except Exception:
print("ERROR RETRIEVING ARRAY: {}".format(arr))
err = c.get_status()
c.close()
print err
pass
c.close()
def checkDateInDB(da):
y = int(da[0:4])
m = int(da[4:6])
d = int(da[6:8])
dquery = "SELECT id FROM card_history_dates WHERE year = {0} AND month = {1} AND day = {2};".format(y, m, d)
# dquery = "SELECT id FROM WellData.card_history_dates WHERE year = 2016 AND month = 1 AND day = 5;"
con.connect()
cur = con.cursor()
cur.execute(dquery)
dates = cur.fetchall()
if len(dates) > 0:
print("Date {0} already in db".format(da))
else:
ins_query = "INSERT INTO card_history_dates (year, month, day, first_id) VALUES ({0}, {1}, {2}, (SELECT MAX(id) FROM card_history));".format(y, m, d)
print(ins_query)
con.connect()
cur = con.cursor()
cur.execute(ins_query)
con.commit()
class Status(Tag):
def sendToDB(self):
query = "INSERT INTO run_status (dtime, status) VALUES ({}, '{}')".format(time.time(), self.value)
print query
con.connect()
cur = con.cursor()
cur.execute(query)
con.commit()
self.last_send_time = time.time()
# ---------- MAP FUNCTIONS ---------- #
maps = {
'modeMap': {
0: "Error",
1: "Auto",
2: "POC",
3: "Timer",
4: "Manual",
5: "DH PID"
},
'card_type_map': {
0: "Normal",
1: "Shutdown",
2: "Alarm",
3: "Startup",
4: "Low Fillage"
},
'statusMap': {
0: 'Stopped',
1: 'Running',
2: 'Pumped Off',
3: 'Faulted',
4: 'Starting',
5: 'Recovering',
100: 'Read Error',
1000: 'PLC Error',
9999: 'No Response'
},
'conditionMap': {
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"
}
}
# ---------- TAGS ---------- #
stroke_tags = {} # Tags stored for every single stroke
history_tags = {} # Tags stored on value change or age
gaugeoff_tags = {} # Tags stored at gauge off
welltest_tags = {} # Tags stored at well test submit
bit_tags = {}
safety_tags = {}
custom_tags = {}
status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'])
def setupTags():
con.connect()
cur = con.cursor()
query = "SELECT t.name as name, c.tag_class as class, t.tag as tag, t.data_type as data_type, t.change_threshold as change_threshold, t.guarantee_sec as guarantee_sec, t.id as id, t.map_function as map_function FROM tags t JOIN tag_classes c ON c.id = t.class;"
cur.execute(query)
tags = cur.fetchall()
# (u'downhole_gross_stroke', u'history', u'Card_Past[1].Downhole_GrossStroke', u'REAL', 2.0, 3600, 6, None)
# 0: name, 1: class, 2: tag, 3: data_type, 4: change_threshold, 5: guarantee_sec, 6: db id, 7: map_function
for x in tags:
print(x)
if str(x[1]) == 'stroke':
if x[7]:
stroke_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5], mapFn=maps[str(x[7])])
else:
stroke_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5])
elif str(x[1]) == 'history':
if x[7]:
history_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5], mapFn=maps[str(x[7])])
else:
history_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5])
elif str(x[1]) == 'gaugeoff':
if x[7]:
gaugeoff_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5], mapFn=maps[str(x[7])])
else:
gaugeoff_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5])
elif str(x[1]) == 'welltest':
if x[7]:
welltest_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5], mapFn=maps[str(x[7])])
else:
welltest_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5])
elif str(x[1]) == 'custom':
if x[7]:
custom_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5], mapFn=maps[str(x[7])])
else:
custom_tags[x[0]] = Tag(str(x[0]), str(x[2]), x[6], str(x[3]), x[4], x[5])
con.connect()
cur = con.cursor()
query = "SELECT c.alarm_class as class, a.name as name, a.tag as tag, a.cond as cond, a.id as id FROM alarms a JOIN alarm_classes c ON a.class = c.id;"
cur.execute(query)
alarms = cur.fetchall()
for x in alarms:
# 0: class, 1: name, 2: tag, 3: condition
if str(x[0]) == 'analog':
safety_tags[x[1]] = AnalogAlarm(str(x[1]), str(x[2]), int(x[4]), device_type="CLX", ip_address=configProperties['PLC_IP_ADDRESS'])
elif str(x[0]) == 'bit':
bit_tags[x[1]] = bitAlarm(str(x[1]), str(x[2]), str(x[3]), int(x[4]), device_type="CLX", ip_address=configProperties['PLC_IP_ADDRESS'])
print('===== STROKE TAGS =====')
for t in stroke_tags:
print(t)
print('===== HISTORY TAGS =====')
for t in history_tags:
print(t)
print('===== WELLTEST TAGS =====')
for t in welltest_tags:
print(t)
print('===== GAUGEOFF TAGS =====')
for t in gaugeoff_tags:
print(t)
print('===== BIT SAFETIES =====')
for t in bit_tags:
print(t)
print('===== ANALOG SAFETIES =====')
for t in safety_tags:
print(t)
print('===== CUSTOM TAGS =====')
for t in custom_tags:
print(t)
setupTags()
def readPoints():
global configProperties
num_points = readTag(configProperties['PLC_IP_ADDRESS'], "Card_Past[1].Num_Points")[0]
surf_pos = readArray(configProperties['PLC_IP_ADDRESS'], "Card_Past[1].Surface_Position", num_points + 1)[1:]
surf_pos.append(surf_pos[0])
surf_lod = readArray(configProperties['PLC_IP_ADDRESS'], "Card_Past[1].Surface_Load", num_points + 1)[1:]
surf_lod.append(surf_lod[0])
down_pos = readArray(configProperties['PLC_IP_ADDRESS'], "Card_Past[1].Downhole_Position", num_points + 1)[1:]
down_pos.append(down_pos[0])
down_lod = readArray(configProperties['PLC_IP_ADDRESS'], "Card_Past[1].Downhole_Load", num_points + 1)[1:]
down_lod.append(down_lod[0])
return([surf_pos, surf_lod, down_pos, down_lod])
def evalTapers():
global configProperties
ts = time.time()
numTapers = int(readTag(configProperties['PLC_IP_ADDRESS'], 'Card_Current.Params.Num_Tapers')[0])
for t in range(1, numTapers + 1):
taper_length = readTag(configProperties['PLC_IP_ADDRESS'], 'Taper.Taper[{}].Setup.Length'.format(t))[0]
taper_diameter = readTag(configProperties['PLC_IP_ADDRESS'], 'Taper.Taper[{}].Setup.Diameter'.format(t))[0]
taper_material = readTag(configProperties['PLC_IP_ADDRESS'], 'Taper.Taper[{}].Setup.Material'.format(t))[0]
if (taper_material == 1):
taper_material = "Steel"
elif (taper_material == 2):
taper_material = "Fiberglass"
tStr = "{{'taper':{}, 'length': {}, 'diameter': {}, 'material':'{}'}}".format(t, taper_length, taper_diameter, taper_material)
tQuery = 'INSERT INTO well_config (tstamp, type, val) VALUES ({}, "taper", "{}")'.format(ts, tStr)
print tQuery
con.connect()
cur = con.cursor()
cur.execute(tQuery)
con.commit()
pump_diameter = readTag(configProperties['PLC_IP_ADDRESS'], 'UnitConfig.Pump_Diameter')[0]
cfgQuery = "INSERT INTO well_config (tstamp, type, val) VALUES ({}, 'pump_diameter', '{}')".format(ts, pump_diameter)
con.connect()
cur = con.cursor()
cur.execute(cfgQuery)
con.commit()
print "TAPER DATA READ!"
return True
def main():
global configProperties
read_tapers = False
already_gauged_off = False
already_entered_well_test = False
last_date = ""
last_stroke = 0
last_status = ""
statusChanged = False
while True:
try:
current_status = status.read("test")
statusChanged = not (current_status == last_status)
if statusChanged:
last_status = current_status
#############
# CARD DATA #
#############
EOS = readTag(configProperties['PLC_IP_ADDRESS'], "End_Of_Stroke")[0]
stroke_tags['card_id'].read('test')
if (EOS and not (last_stroke == stroke_tags['card_id'].value)):
sData = {}
last_stroke = stroke_tags['card_id'].value
stroke_time = time.time()
dt = datetime.fromtimestamp(stroke_time)
sData['localtime'] = dt
sData['stroke_time'] = dt
sData['utctime'] = datetime.utcfromtimestamp(stroke_time)
for t in stroke_tags:
stroke_tags[t].read(True)
[sData['Surface_Position'], sData['Surface_Load'], sData['Downhole_Position'], sData['Downhole_Load']] = readPoints()
# st = datetime.strftime(dt, "%Y%m%d_%H%M%S")
date = datetime.strftime(dt, "%Y%m%d")
if not date == last_date:
checkDateInDB(date)
last_date = date
sData["card_type"] = stroke_tags['card_type'].value
sData["card_id"] = stroke_tags['card_id'].value
sData['sp_string'] = ', '.join(map(str, sData['Surface_Position']))
sData['sl_string'] = ', '.join(map(str, sData['Surface_Load']))
sData['dp_string'] = ', '.join(map(str, sData['Downhole_Position']))
sData['dl_string'] = ', '.join(map(str, sData['Downhole_Load']))
insert_query = "INSERT INTO card_history (Card_ID, Card_Type, Stroke_Time, Surface_Position, Surface_Load, Downhole_Position, Downhole_Load) VALUES (:card_id, :card_type, :stroke_time, :sp_string, :sl_string, :dp_string, :dl_string)"
con.connect()
cur = con.cursor()
cur.execute(insert_query, sData)
con.commit()
print "CARD NUMBER " + str(sData["card_id"]) + " READ!"
###################
# HISTORICAL DATA #
###################
for hist in history_tags:
h = history_tags[hist]
h.read("test")
for cust in custom_tags:
t = custom_tags[cust]
t.read("test")
##############
# TAPER DATA #
##############
update_taper = readTag(configProperties['PLC_IP_ADDRESS'], "Write_Tapers")[0] > 0
if (update_taper == 0):
if read_tapers:
read_tapers = False
print "Update Tapers = False"
if (update_taper and (not read_tapers)):
print "reading taper file"
read_tapers = evalTapers()
##################
# GAUGE OFF DATA #
##################
gauge_off = readTag(configProperties['PLC_IP_ADDRESS'], "Gauge_Off_Command")[0]
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..."
for goff in gaugeoff_tags:
g = gaugeoff_tags[goff]
g.read(True)
gauge_date = datetime(year=gaugeoff_tags['year'].value, month=gaugeoff_tags['month'].value, day=gaugeoff_tags['day'].value, hour=gaugeoff_tags['hour'].value, minute=gaugeoff_tags['min'].value, second=gaugeoff_tags['sec'].value)
con.connect()
cur = con.cursor()
con.execute("""INSERT INTO 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, gaugeoff_tags['percent_run'].value, gaugeoff_tags['kwh'].value, gaugeoff_tags['electricity_cost'].value, gaugeoff_tags['max_load'].value, gaugeoff_tags['min_load'].value, gaugeoff_tags['average_spm'].value, gaugeoff_tags['production_calculated'].value, gaugeoff_tags['full_card_production'].value, gaugeoff_tags['polished_rod_hp'].value, gaugeoff_tags['lifting_cost'].value, gaugeoff_tags['fluid_level'].value, gaugeoff_tags['pump_intake_pressure'].value, gaugeoff_tags['kwh_regen'].value, gaugeoff_tags['inflow_rate'].value))
con.commit()
already_gauged_off = True
print "Gauged off!"
##################
# WELL TEST DATA #
##################
well_test_entered = readTag(configProperties['PLC_IP_ADDRESS'], "Well_Test.Test_Submit")[0] > 0
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)):
for wtest in welltest_tags:
w = welltest_tags[wtest]
w.read(True)
print "Well Test Entered"
print('{}/{}/{} {}:{}:{}'.format(welltest_tags['year'].value, welltest_tags['month'].value, welltest_tags['day'].value, welltest_tags['hour'].value, welltest_tags['min'].value, welltest_tags['sec'].value))
test_date = datetime(year=welltest_tags['year'].value, month=welltest_tags['month'].value, day=welltest_tags['day'].value, hour=welltest_tags['hour'].value, minute=welltest_tags['min'].value, second=welltest_tags['sec'].value)
con.connect()
cur = con.cursor()
test_query = "INSERT INTO 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, welltest_tags['v_oil'].value, welltest_tags['v_water'].value, welltest_tags['v_gas'].value, welltest_tags['k_factor'].value, welltest_tags['p_v_oil'].value, welltest_tags['p_v_water'].value, welltest_tags['api_oil'].value, welltest_tags['sg_water'].value, welltest_tags['test_duration'].value)
# print test_query
con.execute(test_query)
con.commit()
already_entered_well_test = True
print "Well Test Stored!"
###################
# ALARMS & EVENTS #
###################
for t in safety_tags:
safety_tags[t].checkStatus(stroke_tags['card_id'].value)
for b in bit_tags:
bit_tags[b].checkStatus(stroke_tags['card_id'].value)
time.sleep(.20)
except Exception, e:
print("Error during loop: {}".format(e))
traceback.print_exc()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,57 @@
import mysql.connector as mysqlcon
import pickle
import os
with open(os.path.realpath('.') + '/mysql_cfg.pickle', 'rb') as cfgFile:
mysql_cfg = pickle.load(cfgFile)
con = mysqlcon.connect(**mysql_cfg)
def readConfig():
configProperties = {}
configObj = {}
con.connect()
cur = con.cursor()
query = "SELECT parameter, val FROM config GROUP BY parameter;"
cur.execute(query)
config = cur.fetchall()
for x in config:
configObj[x[0]] = x[1]
try:
configProperties['PLC_IP_ADDRESS'] = str(configObj['ip_address'])
print("FYI, using PLC IP Address from the database {0}".format(configProperties['PLC_IP_ADDRESS']))
except KeyError:
print("FYI, there is no PLC IP Address stored in the database, defaulting to 192.168.1.10")
configProperties['PLC_IP_ADDRESS'] = "192.168.1.10"
try:
configProperties['plc_type'] = str(configObj['plc_type'])
print("FYI, using PLC Type from the database {0}".format(configProperties['plc_type']))
except KeyError:
print("FYI, there is no PLC Type stored in the database, defaulting to CLX")
configProperties['plc_type'] = "CLX"
try:
configProperties['scan_rate'] = int(configObj['scan_rate'])
print("FYI, using Scan Rate from the database {0}".format(configProperties['scan_rate']))
except KeyError:
print("FYI, there is no Scan Rate stored in the database, defaulting to 10 seconds")
configProperties['scan_rate'] = 10
try:
sa_test = str(configObj['save_all'])
if sa_test.lower() == "true":
configProperties['save_all'] = True
elif sa_test.lower() == "false":
configProperties['save_all'] = False
else:
configProperties['save_all'] = "test"
print("FYI, value for save_all is {0}".format(configProperties['save_all']))
except KeyError:
print("FYI, there is no save_all value stored in the database, using 'test'")
configProperties['save_all'] = 'test'
return configProperties

View File

@@ -163,7 +163,7 @@ CREATE TABLE IF NOT EXISTS alarms(
name TEXT,
class INTEGER,
tag TEXT,
condition TEXT
cond TEXT
);
INSERT INTO tag_classes (id, tag_class, description) VALUES (1, 'stroke', 'Stroke Information');

View File

@@ -1,74 +1,20 @@
#!/usr/bin/env python
'''
Created on Oct 1, 2014
@author: Patrick McDonagh
'''
# import csv
from datetime import datetime
import time
import sqlite3 as lite
from pycomm.ab_comm.clx import Driver as ClxDriver
# import logging
from tag.tag_sqlite import Tag
from tag.tag_sqlite import AnalogAlarm
from tag.tag_sqlite import bitAlarm
from readConfig_SQLite import readConfig
import traceback
con = lite.connect("/mnt/usb/data.db")
# con = lite.connect("/Users/patrickjmcd/Desktop/data.db")
configProperties = {}
def readConfig():
global configProperties
configObj = {}
with con:
cur = con.cursor()
query = "SELECT parameter, val FROM config GROUP BY parameter;"
cur.execute(query)
config = cur.fetchall()
for x in config:
configObj[x[0]] = x[1]
try:
configProperties['PLC_IP_ADDRESS'] = str(configObj['ip_address'])
print("FYI, using PLC IP Address from the database {0}".format(configProperties['PLC_IP_ADDRESS']))
except KeyError:
print("FYI, there is no PLC IP Address stored in the database, defaulting to 192.168.1.10")
configProperties['PLC_IP_ADDRESS'] = "192.168.1.10"
try:
configProperties['plc_type'] = str(configObj['plc_type'])
print("FYI, using PLC Type from the database {0}".format(configProperties['plc_type']))
except KeyError:
print("FYI, there is no PLC Type stored in the database, defaulting to CLX")
configProperties['plc_type'] = "CLX"
try:
configProperties['scan_rate'] = int(configObj['scan_rate'])
print("FYI, using Scan Rate from the database {0}".format(configProperties['scan_rate']))
except KeyError:
print("FYI, there is no Scan Rate stored in the database, defaulting to 10 seconds")
configProperties['scan_rate'] = 10
try:
sa_test = str(configObj['save_all'])
if sa_test.lower() == "true":
configProperties['save_all'] = True
elif sa_test.lower() == "false":
configProperties['save_all'] = False
else:
configProperties['save_all'] = "test"
print("FYI, value for save_all is {0}".format(configProperties['save_all']))
except KeyError:
print("FYI, there is no save_all value stored in the database, using 'test'")
configProperties['save_all'] = 'test'
try:
readConfig()
configProperties = readConfig()
except:
traceback.print_exc()
@@ -225,7 +171,7 @@ def setupTags():
with con:
cur = con.cursor()
query = "SELECT c.alarm_class as class, a.name as name, a.tag as tag, a.condition as condition, a.id as id FROM alarms a JOIN alarm_classes c ON a.class = c.id;"
query = "SELECT c.alarm_class as class, a.name as name, a.tag as tag, a.cond as condition, a.id as id FROM alarms a JOIN alarm_classes c ON a.class = c.id;"
cur.execute(query)
alarms = cur.fetchall()
for x in alarms:
@@ -259,6 +205,9 @@ def setupTags():
for t in safety_tags:
print(t)
print('===== CUSTOM TAGS =====')
for t in custom_tags:
print(t)
setupTags()
@@ -373,7 +322,7 @@ def main():
h.read("test")
for cust in custom_tags:
t = custom_tags[hist]
t = custom_tags[cust]
t.read("test")
##############

View File

@@ -0,0 +1,52 @@
import sqlite3 as lite
con = lite.connect("/mnt/usb/data.db")
def readConfig():
configProperties = {}
configObj = {}
with con:
cur = con.cursor()
query = "SELECT parameter, val FROM config GROUP BY parameter;"
cur.execute(query)
config = cur.fetchall()
for x in config:
configObj[x[0]] = x[1]
try:
configProperties['PLC_IP_ADDRESS'] = str(configObj['ip_address'])
print("FYI, using PLC IP Address from the database {0}".format(configProperties['PLC_IP_ADDRESS']))
except KeyError:
print("FYI, there is no PLC IP Address stored in the database, defaulting to 192.168.1.10")
configProperties['PLC_IP_ADDRESS'] = "192.168.1.10"
try:
configProperties['plc_type'] = str(configObj['plc_type'])
print("FYI, using PLC Type from the database {0}".format(configProperties['plc_type']))
except KeyError:
print("FYI, there is no PLC Type stored in the database, defaulting to CLX")
configProperties['plc_type'] = "CLX"
try:
configProperties['scan_rate'] = int(configObj['scan_rate'])
print("FYI, using Scan Rate from the database {0}".format(configProperties['scan_rate']))
except KeyError:
print("FYI, there is no Scan Rate stored in the database, defaulting to 10 seconds")
configProperties['scan_rate'] = 10
try:
sa_test = str(configObj['save_all'])
if sa_test.lower() == "true":
configProperties['save_all'] = True
elif sa_test.lower() == "false":
configProperties['save_all'] = False
else:
configProperties['save_all'] = "test"
print("FYI, value for save_all is {0}".format(configProperties['save_all']))
except KeyError:
print("FYI, there is no save_all value stored in the database, using 'test'")
configProperties['save_all'] = 'test'
return configProperties

View File

@@ -1,18 +1,7 @@
import csv
from datetime import datetime
import os
import sys
from random import randint
import time
import sqlite3 as lite
import logging
from pycomm.ab_comm.clx import Driver as ClxDriver
import traceback
import math
con = lite.connect("/mnt/usb/data.db")
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
from readConfig import readConfig
today_tags = [
{'name':"Average_SPM",'tag':"TODAY_Average_SPM"},
@@ -37,20 +26,6 @@ today_tags = [
]
def readConfig():
global PLC_IP_ADDRESS, PLC_TYPE
with con:
cur = con.cursor()
query = "SELECT * FROM config ORDER BY dateChanged DESC LIMIT 1;"
cur.execute(query)
setup = cur.fetchall()
try:
PLC_IP_ADDRESS = setup[0][2]
PLC_TYPE = setup[0][1]
except:
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
retry_attempts = 0
retries_allowed = 10
@@ -74,12 +49,12 @@ def readTag(addr, tag):
c.close()
def main():
global PLC_IP_ADDRESS, today_tags, retry_attempts, retries_allowed
global today_tags, retry_attempts, retries_allowed
try:
readConfig()
configProperties = readConfig()
outList = []
for tag in today_tags:
val = readTag(PLC_IP_ADDRESS, tag['tag'])[0]
val = readTag(configProperties['PLC_IP_ADDRESS'], tag['tag'])[0]
if not math.isnan(val):
outList.append({'name':tag['name'], 'value':val})
print outList

View File

@@ -1,44 +1,21 @@
#!/usr/bin/env python
import os
import sys
import sqlite3 as lite
from pycomm.ab_comm.clx import Driver as ClxDriver
from readConfigimport readConfig
con = lite.connect("/mnt/usb/data.db")
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
def getPLCIP():
global PLC_IP_ADDRESS, PLC_TYPE
with con:
cur = con.cursor()
query = "SELECT * FROM config ORDER BY dateChanged DESC LIMIT 1;"
cur.execute(query)
setup = cur.fetchall()
try:
PLC_IP_ADDRESS = setup[0][2]
PLC_TYPE = setup[0][1]
except:
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
return
configProperties = readConfig()
def main(tagName):
global PLC_IP_ADDRESS
getPLCIP()
c = ClxDriver()
global configProperties
c = ClxDriver()
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):
if c.open(configProperties['PLC_IP_ADDRESS']):
out = {}
try:
result = c.read_tag([tagName])

View File

@@ -1,111 +1,64 @@
#!/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
from readConfig import readConfig
from pycomm.ab_comm.clx import Driver as ClxDriver
def readTag(addr, tag):
time.sleep(0.01)
c = ClxDriver()
if c.open(addr):
try:
v = c.read_tag(tag)
# print(v)
return v
except Exception:
print("ERROR RETRIEVING TAG: {}".format(tag))
c.close()
print traceback.print_exc()
pass
c.close()
def writeTag(addr, tag, val, dtype):
time.sleep(0.01)
c = ClxDriver()
if c.open(addr):
try:
v = c.write_tag(tag, val, dtype)
# print(v)
return v
except Exception:
print("ERROR WRITING TAG: {}".format(tag))
c.close()
print traceback.print_exc()
pass
c.close()
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
configProperties = readConfig()
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()
with open(fullfilepath, 'rb') as myfile:
wr = csv.reader(myfile)
for row in wr:
if len(row) == 3:
(tag, value, tagType) = row
writeTag(configProperties['PLC_IP_ADDRESS'], tag, value, tagType)
actual = readTag(configProperties['PLC_IP_ADDRESS'], tag)
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,")")
print "Restore Complete with", len(errors), "errors."
if len(errors) > 0:
print "-------------------------"

6
setdb_MySQL.sh Normal file
View File

@@ -0,0 +1,6 @@
echo "Setting database type to MySQL"
cp dbMySQL/dataLogger_MySQL.py dataLogger.py
cp dbMySQL/readConfig_MySQL.py readConfig.py
cp dbMySQL/mysql_cfg.pickle mysql_cfg.pickle
echo "Done!"

5
setdb_SQLite.sh Normal file
View File

@@ -0,0 +1,5 @@
echo "Setting database type to MySQL"
cp dbSQLite/dataLogger_SQLite.py dataLogger.py
cp dbSQLite/readConfig_SQLite.py readConfig.py
echo "Done!"

View File

@@ -79,14 +79,14 @@ INSERT INTO alarms (name, class, tag) VALUES ('Speed', 1, 'Safety_Speed');
INSERT INTO alarms (name, class, tag) VALUES ('Load LoLo', 1, 'Safety_Load_LoLo');
INSERT INTO alarms (name, class, tag) VALUES ('Inclinometer', 1, 'Safety_Inclinometer');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Unit Jogged', 2, 'Pump.Jog', 'Unit Jog');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Restart (Auto Mode)', 2, 'Pump.Auto_Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Pump Off (POC Mode)', 2, 'Pump.POC_Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Restart (Timer Mode)', 2, 'Pump.Timed_Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Restart (POC Mode)', 2, 'Pump.POC_Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Pump Off (Auto Mode)', 2, 'Pump.Auto_Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Peak Energy Restart', 2, 'PeakEnergy.Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Peak Energy Stop', 2, 'PeakEnergy.Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, condition) VALUES ('User Initiated Start', 2, 'Pump.Start', 'Unit Start');
INSERT INTO alarms (name, class, tag, condition) VALUES ('User Initiated Stop', 2, 'Pump.Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, condition) VALUES ('Pump Off (Timer Mode)', 2, 'Pump.Timed_Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Unit Jogged', 2, 'Pump.Jog', 'Unit Jog');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Restart (Auto Mode)', 2, 'Pump.Auto_Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Pump Off (POC Mode)', 2, 'Pump.POC_Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Restart (Timer Mode)', 2, 'Pump.Timed_Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Restart (POC Mode)', 2, 'Pump.POC_Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Pump Off (Auto Mode)', 2, 'Pump.Auto_Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Peak Energy Restart', 2, 'PeakEnergy.Restart', 'Unit Start');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Peak Energy Stop', 2, 'PeakEnergy.Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, cond) VALUES ('User Initiated Start', 2, 'Pump.Start', 'Unit Start');
INSERT INTO alarms (name, class, tag, cond) VALUES ('User Initiated Stop', 2, 'Pump.Stop', 'Unit Stop');
INSERT INTO alarms (name, class, tag, cond) VALUES ('Pump Off (Timer Mode)', 2, 'Pump.Timed_Stop', 'Unit Stop');

View File

@@ -1,41 +1,17 @@
from pycomm.ab_comm.clx import Driver as ClxDriver
import sys
from time import sleep
import sqlite3 as lite
con = lite.connect("/mnt/usb/data.db")
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
from readConfig import readConfig
def closeEnough(a,b):
return abs(a - b) <= 0.1
def getPLCIP():
global PLC_IP_ADDRESS, PLC_TYPE
with con:
cur = con.cursor()
query = "SELECT * FROM config ORDER BY dateChanged DESC LIMIT 1;"
cur.execute(query)
setup = cur.fetchall()
try:
PLC_IP_ADDRESS = setup[0][2]
PLC_TYPE = setup[0][1]
except:
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
return
def readTag(tagName):
global PLC_IP_ADDRESS
configProperties = readConfig()
def readTag(addr, tag):
time.sleep(0.01)
c = ClxDriver()
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):
if c.open(configProperties['PLC_IP_ADDRESS']):
out = {}
try:
result = c.read_tag([tagName])
@@ -50,10 +26,9 @@ def readTag(tagName):
c.close()
return out
def main(tag, value):
global PLC_IP_ADDRESS
getPLCIP()
def main(tag, value):
global configProperties
r = 0
readObj = readTag(tag)
@@ -67,7 +42,7 @@ def main(tag, value):
elif tagType == "REAL":
value = float(value)
c = ClxDriver()
if c.open(PLC_IP_ADDRESS):
if c.open(configProperties['PLC_IP_ADDRESS']):
r = c.write_tag(tag, value, tagType)
else:
return {"status": 'error', "message": "not connected to PLC"}
@@ -79,9 +54,8 @@ def main(tag, value):
def writeTagAndVerify(tag,value, sleepValue=2):
"""Writes the specified value to tag and confirms that the value has been set"""
global PLC_IP_ADDRESS
global configProperties
r = 0
getPLCIP()
readObj = readTag(tag)
if readObj['status'] == "error":
@@ -94,7 +68,7 @@ def writeTagAndVerify(tag,value, sleepValue=2):
elif tagType == "REAL":
value = float(value)
c = ClxDriver()
if c.open(PLC_IP_ADDRESS):
if c.open(configProperties['PLC_IP_ADDRESS']):
r = c.write_tag(tag, value, tagType)
sleep(float(sleepValue))
newObj = readTag(tag)