Files
datalogger-POC/dataLogger_pycomm.py
Patrick McDonagh 340ac5ab60 Initial Commit
2015-12-08 22:19:39 -06:00

331 lines
16 KiB
Python

#!/usr/bin/env python
'''
Created on Oct 1, 2014
@author: PJMcdona
'''
#from prettytable import PrettyTable
import csv
from datetime import datetime
import os
import sys
from random import randint
import time
import MySQLdb
def main():
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
cur = db.cursor()
query = "SELECT * FROM WellData.config ORDER BY dateChanged DESC LIMIT 1;"
cur.execute(query)
setup = cur.fetchall()
db.commit()
db.close()
try:
PLC_IP_ADDRESS = setup[0][2]
PLC_TYPE = setup[0][1]
except:
print("PLC Address not set in database... using default of 192.168.1.10")
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
sys.path.append("../")
path_to_CSV = "/mnt/usb/"
#PYCOMM Connection to PLC
from pycomm.ab_comm.clx import Driver as ClxDriver
c = ClxDriver(True, 'ClxDriver.log')
if os.path.exists(path_to_CSV + "current.csv"):
os.remove(path_to_CSV + "current.csv")
tags_to_read = [['Card_Past[1].ID', 'INT', "Card_ID"],
['Card_Past[1].Params.Num_Tapers', 'INT', 'Num_Tapers'],
['Card_Past[1].Num_Points', 'INT', 'Num_Points'],
['Card_Past[1].Card_Type', 'INT', 'Card_Type'],
['Card_Past[1].End_Time.Year', 'INT', '_Year'],
['Card_Past[1].End_Time.Month', 'INT', '_Month'],
['Card_Past[1].End_Time.Day', 'INT', '_Day'],
['Card_Past[1].End_Time.Hour', 'INT', '_Hour'],
['Card_Past[1].End_Time.Min', 'INT', '_Minute'],
['Card_Past[1].End_Time.Sec', 'INT', '_Second'],
#['Card_Past[1].Name.Data[0]','STRING', 'Well_Name'],
['Card_Past[1].Params.Tubing_Head_Pressure','REAL', 'Tubing_Head_Pressure'],
['Card_Past[1].Params.Fluid_Gradient','REAL', 'Fluid_Gradient'],
['Card_Past[1].Params.Stuffing_Box_Friction','REAL', 'Stuffing_Box_Friction'],
['Card_Past[1].Params.dt','REAL', 'dt'],
# ['Card_Past[1].Downhole_Max_Load.Load','REAL', 'Downhole_Max_Load'],
# ['Card_Past[1].Downhole_Min_Load.Load','REAL', 'Downhole_Min_Load'],
# ['Card_Past[1].Downhole_Max_Position.Position','REAL', 'Downhole_Max_Position'],
# ['Card_Past[1].Downhole_Min_Position.Position','REAL', 'Downhole_Min_Position'],
['Card_Past[1].Downhole_GrossStroke','REAL', 'Downhole_Gross_Stroke'],
['Card_Past[1].Downhole_AdjustedGrossStroke','REAL', 'Downhole_Adjusted_Gross_Stroke'],
['Card_Past[1].Downhole_NetStroke','REAL', 'Downhole_Net_Stroke'],
['Card_Past[1].Downhole_FluidLoad','REAL', 'Downhole_Fluid_Load'],
['Card_Past[1].Surface_Max.Load','REAL', 'Surface_Max_Load'],
['Card_Past[1].Surface_Min.Load','REAL', 'Surface_Min_Load'],
# ['Card_Past[1].Surface_Max.Position','REAL', 'Surface_Max_Position'],
# ['Card_Past[1].Surface_Min.Position','REAL', 'Surface_Min_Position'],
['Card_Past[1].Tubing_Movement','REAL', 'Tubing_Movement'],
['Card_Past[1].Surface_StrokeLength','REAL', 'Surface_Stroke_Length'],
['Card_Past[1].Fillage_Percent','REAL', 'Fillage_Percent'],
['Card_Past[1].Polished_Rod_HP','REAL', 'Polished_Rod_HP'],
['Card_Past[1].Pump_HP','REAL', 'Pump_HP'],
['Card_Past[1].SPM','REAL', 'SPM'],
['Card_Past[1].Fluid_Above_Pump','REAL', 'Fluid_Above_Pump'],
['Stroke_Production','REAL', 'Stroke_Production'],
['Pump_Intake_Pressure','REAL', 'Pump_Intake_Pressure'],
]
def readString(tag):
read_vals = c.read_array(tag, 82)
string = filter(lambda b: b != "",map(lambda a: chr(a[1]),read_vals))
return "".join(string)
cards_read = 1
read_tapers = False
already_gauged_off = False
already_entered_well_test = False
try:
if c.open(PLC_IP_ADDRESS):
while True:
data = {}
now = datetime.now()
run_status = c.read_tag(['Pump.Run_Status'])[0][1]
card_id = c.read_tag(['Card_Past[1].ID'])[0][1]
fillage_percent = c.read_tag(['Card_Past[1].Fillage_Percent'])[0][1]
fluid_above_pump = c.read_tag(['Card_Past[1].Fluid_Above_Pump'])[0][1]
stroke_production = c.read_tag(['Stroke_Production'])[0][1]
with open('/mnt/usb/status.txt', 'w') as status_file:
status_file.write("{0}-->{1}\n{2},{3},{4},{5}".format(datetime.strftime(now,"%Y%m%d_%H%M%S"), run_status, card_id, fillage_percent, fluid_above_pump, stroke_production))
#############
# CARD DATA #
#############
EOS = c.read_tag(["End_Of_Stroke"])[0][1]
Already_Read = c.read_tag(["Card_Past[1].Data_Read"])[0][1] > 0
if (EOS and not Already_Read and (EOS != 911)):
num_points = c.read_tag(["Card_Past[1].Num_Points"])[0][1]
data['Well_Name'] = readString('Card_Past[1].Name.Data')
filename = path_to_CSV + "current.csv"
myfile = open(filename, 'wb')
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
stroke_time = time.time()
dt = datetime.fromtimestamp(stroke_time)
wr.writerow(['localtime', dt])
wr.writerow(['utctime', datetime.utcfromtimestamp(stroke_time)])
# wr.writerow(["Well_Name",data["Well_Name"]])
for t in tags_to_read:
data[t[2]] = c.read_tag([t[0]])[0][1]
wr.writerow([t[2],data[t[2]]])
numPointsRead = num_points + 1
sp = c.read_array("Card_Past[0].Surface_Position", numPointsRead)
sl = c.read_array("Card_Past[0].Surface_Load", numPointsRead)
dp = c.read_array("Card_Past[0].Downhole_Position", numPointsRead)
dl = c.read_array("Card_Past[0].Downhole_Load", numPointsRead)
wr.writerow(["s_pos", "s_load"])
for i in range(0, numPointsRead):
if sp[i][1] and (sp[i][1] != 0.0) and sl[i][1]:
wr.writerow([round(sp[i][1],3), round(sl[i][1],3)])
wr.writerow(["d_pos", "d_load"])
for i in range(1, numPointsRead):
if dp[i][1] and (dp[i][1] != 0.0) and dl[i][1]:
wr.writerow([round(dp[i][1],3), round(dl[i][1],3)])
myfile.close()
dt = datetime(year = data["_Year"], month = data["_Month"],day = data["_Day"],hour = data["_Hour"],minute = data["_Minute"],second = data["_Second"])
st = datetime.strftime(dt,"%Y%m%d_%H%M%S")
date = datetime.strftime(dt,"%Y%m%d")
if (data["Card_Type"] == 0):
data["Card_Type"] = "Normal"
elif (data["Card_Type"]==1):
data["Card_Type"] = "Shutdown"
elif (data["Card_Type"]==2):
data["Card_Type"] = "Alarm"
elif (data["Card_Type"]==3):
data["Card_Type"] = "Startup"
else:
data["Card_Type"] ="Unknown"
if not os.path.exists(path_to_CSV +"CSV/"+date):
os.makedirs(path_to_CSV+"CSV/"+date)
fill_percent_file = str(round(data['Fillage_Percent'],3)).replace(".","-")
rename_file = path_to_CSV+"CSV/"+ date+"/"+st+"_"+str(data["Card_ID"])+"_"+data['Card_Type']+ "_"+fill_percent_file +".csv"
os.rename(filename, rename_file)
c.write_tag('Card_Past[1].Data_Read', 1, 'REAL')
print "CARD NUMBER " + str(cards_read) + " READ: "+str(data["Card_ID"])+ ", STORED AS "+ rename_file
cards_read = cards_read + 1
##############
# TAPER DATA #
##############
update_taper = c.read_tag(["Write_Tapers"])[0][1]
if (update_taper == 0):
if read_tapers:
read_tapers = False
print "Update Tapers = False"
if (update_taper and (not read_tapers) and (update_taper != 911)):
print "reading taper file"
taper_count = 0;
tFilename = path_to_CSV + "CSV/TAPER/TAPER_" + datetime.strftime(now,"%Y%m%d_%H%M%S")+ '.CSV'
tFile = open(tFilename, 'wb')
twr = csv.writer(tFile, quoting=csv.QUOTE_ALL)
for taps in range(1,10):
taper_in_use_temp = c.read_tag(['Taper.Taper[' + str(taps)+'].Calculated.InUse'])[0][1]
if taper_in_use_temp:
taper_count = taper_count + 1
#print "reading Taper"+ str(taper_count)
twr.writerow(["Taper",taper_count])
twr.writerow(['Length',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Length'])[0][1]])
twr.writerow(['Diameter',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Diameter'])[0][1]])
tMaterial = c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Material'])[0][1]
if (tMaterial == 1):
twr.writerow(['Material',"Steel"])
elif (tMaterial == 2):
twr.writerow(['Material',"Fiberglass"])
twr.writerow(['Weight_Per_Foot', c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Weight'])[0][1]])
twr.writerow(['Youngs_Modulus',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.Youngs_Modulus'])[0][1]])
twr.writerow(['Damping_Factor',c.read_tag(['Taper.Taper['+str(taps) +'].Setup.c'])[0][1]])
twr.writerow(['Area',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Area'])[0][1]])
twr.writerow(['Rod_Depth',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Rod_Depth'])[0][1]])
twr.writerow(['Pressure',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Pressure'])[0][1]])
twr.writerow(['Buoyant_Force',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Buoyant_Force'])[0][1]])
twr.writerow(['Rod_Weight',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Rod_Weight_Air'])[0][1]])
twr.writerow(['Force',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Force'])[0][1]])
twr.writerow(['Stretch',c.read_tag(['Taper.Taper['+str(taps) +'].Calculated.Stretch'])[0][1]])
twr.writerow(["",""])
else:
break
twr.writerow(["UnitConfig",""])
twr.writerow(['Pump_Diameter',c.read_tag(['UnitConfig.Pump_Diameter'])[0][1]])
tFile.close()
read_tapers = True
print "TAPER DATA READ: "+ tFilename
##################
# GAUGE OFF DATA #
##################
gauge_off = c.read_tag(['Gauge_Off_Command'])[0][1]
if (gauge_off == 0):
if already_gauged_off:
already_gauged_off = False
print "Already gauged off... Setting gauge_off to False"
if (gauge_off and (not already_gauged_off)):
print "Gauging off..."
gYear = c.read_tag(['GAUGEOFF_DateTime.Year'])[0][1]
gMonth = c.read_tag(['GAUGEOFF_DateTime.Month'])[0][1]
gDay = c.read_tag(['GAUGEOFF_DateTime.Day'])[0][1]
gHour = c.read_tag(['GAUGEOFF_DateTime.Hour'])[0][1]
gMin = c.read_tag(['GAUGEOFF_DateTime.Min'])[0][1]
gSec = c.read_tag(['GAUGEOFF_DateTime.Sec'])[0][1]
gauge_date = datetime(year = gYear, month = gMonth,day = gDay,hour = gHour,minute = gMin,second = gSec)
print "gaugeDate: {0}".format(gauge_date)
percent_run = round(c.read_tag(['GAUGEOFF_Percent_Run'])[0][1],2)
print "percent_run: {0}".format(percent_run)
kWh = round(c.read_tag(['GAUGEOFF_kWh'])[0][1],3)
print "kWh: {0}".format(kWh)
electricity_cost = round(c.read_tag(['GAUGEOFF_Electricity_Cost'])[0][1],2)
print "electricity_cost: {0}".format(electricity_cost)
peak_load = round(c.read_tag(['GAUGEOFF_Max_Load'])[0][1],3)
print "peak_load: {0}".format(peak_load)
min_load = round(c.read_tag(['GAUGEOFF_Min_Load'])[0][1],3)
print "min_load: {0}".format(min_load)
average_SPM = round(c.read_tag(['GAUGEOFF_Average_SPM'])[0][1],4)
print "average_SPM: {0}".format(average_SPM)
production_calculated = round(c.read_tag(['GAUGEOFF_Production_Calculated'])[0][1],2)
print "production_calculated: {0}".format(production_calculated)
full_card_production = round(c.read_tag(['GAUGEOFF_Full_Card_Production'])[0][1],2)
print "full_card_production: {0}".format(full_card_production)
polished_rod_HP = round(c.read_tag(['GAUGEOFF_Polished_Rod_HP'])[0][1],3)
print "polished_rod_HP: {0}".format(polished_rod_HP)
lifting_cost = round(c.read_tag(['GAUGEOFF_Lifting_Cost'])[0][1],4)
print "lifting_cost: {0}".format(lifting_cost)
fluid_above_pump = round(c.read_tag(['GAUGEOFF_Fluid_Above_Pump'])[0][1],2)
print "fluid_above_pump: {0}".format(fluid_above_pump)
pump_intake_pressure = round(c.read_tag(['GAUGEOFF_pump_intake_pressure'])[0][1],2)
print "pump_intake_pressure: {0}".format(pump_intake_pressure)
kWh_regen = round(c.read_tag(['GAUGEOFF_kWh_regen'])[0][1],2)
print "kWh_regen: {0}".format(kWh_regen)
inflow_rate = round(c.read_tag(['GAUGEOFF_Inflow_Rate'])[0][1],4)
print "inflow_rate: {0}".format(inflow_rate)
db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="WellData")
cur = db.cursor()
print """INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate)
storeHist = cur.execute("""INSERT INTO WellData.Hist_Day (gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate) VALUES ('%s', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f', '%f');"""%(gauge_date, percent_run, kWh, electricity_cost, peak_load, min_load, average_SPM, production_calculated, full_card_production, polished_rod_HP, lifting_cost, fluid_above_pump, pump_intake_pressure, kWh_regen, inflow_rate))
db.commit()
db.close()
already_gauged_off = True
print "Gauged off!"
# ##################
# # WELL TEST DATA #
# ##################
well_test_entered = c.read_tag(['Well_Test.Test_Submit'])[0][1]
if (well_test_entered == 0):
if already_entered_well_test:
already_entered_well_test = False
print "Already entered well Test... Setting well_test_entered to False"
if (well_test_entered and (not already_entered_well_test) and well_test_entered != 911):
print "Well Test Entered"
tYear = c.read_tag(['Well_Test.DateTime_Complete.Year'])[0][1]
tMonth = c.read_tag(['Well_Test.DateTime_Complete.Month'])[0][1]
tDay = c.read_tag(['Well_Test.DateTime_Complete.Day'])[0][1]
tHour = c.read_tag(['Well_Test.DateTime_Complete.Hour'])[0][1]
tMin = c.read_tag(['Well_Test.DateTime_Complete.Min'])[0][1]
tSec = c.read_tag(['Well_Test.DateTime_Complete.Sec'])[0][1]
test_date = datetime(year = tYear, month = tMonth,day = tDay,hour = tHour,minute = tMin,second = tSec)
test_duration = round(c.read_tag(['Well_Test.Test_Duration'])[0][1],3)
v_water = round(c.read_tag(['Well_Test.Volume_Water'])[0][1],3)
v_oil = round(c.read_tag(['Well_Test.Volume_Oil'])[0][1],3)
v_gas = round(c.read_tag(['Well_Test.Volume_Gas'])[0][1],3)
p_v_water = round(c.read_tag(['Well_Test.Projected_Volume_Water'])[0][1],3)
p_v_oil = round(c.read_tag(['Well_Test.Projected_Volume_Oil'])[0][1],3)
k_factor = round(c.read_tag(['Well_Test.k_Factor'])[0][1],3)
api_oil = round(c.read_tag(['Well_Test.API_Oil'])[0][1],3)
sg_water = round(c.read_tag(['Well_Test.SG_Water'])[0][1],3)
db = MySQLdb.connect(host="localhost",user="website",passwd="henrypump",db="WellData")
cur = db.cursor()
test_query = "INSERT INTO WellData.Well_Test (test_date, test_volume_oil, test_volume_water, test_volume_gas, k_factor, projected_volume_oil, projected_volume_water, api_gravity_oil, sg_water, test_hours) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}');".format(test_date, v_oil, v_water, v_gas, k_factor, p_v_oil, p_v_water, api_oil, sg_water, test_duration)
print test_query
storeTest = cur.execute(test_query)
db.commit()
db.close()
already_entered_well_test = True
print "Well Test Stored!"
time.sleep(.20)
except Exception, e:
print("FATAL ERROR: Communication Error connecting to the PLC... ", e)
c.forward_close()
c.open(PLC_IP_ADDRESS)
main()
if __name__ == '__main__':
main()