diff --git a/README.md b/README.md new file mode 100644 index 0000000..1bfd462 --- /dev/null +++ b/README.md @@ -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 diff --git a/backupPLC.py b/backupPLC.py index 541ef46..4dc8141 100644 --- a/backupPLC.py +++ b/backupPLC.py @@ -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 diff --git a/calibrateInclinometer.py b/calibrateInclinometer.py deleted file mode 100644 index 178d983..0000000 --- a/calibrateInclinometer.py +++ /dev/null @@ -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() diff --git a/dataLogger.py b/dataLogger.py deleted file mode 100644 index 4aac854..0000000 --- a/dataLogger.py +++ /dev/null @@ -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) diff --git a/dataLoggerMySQL.py b/dataLoggerMySQL.py deleted file mode 100644 index c21a97c..0000000 --- a/dataLoggerMySQL.py +++ /dev/null @@ -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) diff --git a/dataLogger_MySQL.py b/dataLogger_MySQL.py deleted file mode 100644 index 042c758..0000000 --- a/dataLogger_MySQL.py +++ /dev/null @@ -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() diff --git a/dataLogger_pycomm_mysql.py b/dataLogger_pycomm_mysql.py deleted file mode 100644 index 2e304a2..0000000 --- a/dataLogger_pycomm_mysql.py +++ /dev/null @@ -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) diff --git a/create_MySQL_db.sql b/dbMySQL/create_MySQL_db.sql similarity index 87% rename from create_MySQL_db.sql rename to dbMySQL/create_MySQL_db.sql index c966be2..2d040bd 100644 --- a/create_MySQL_db.sql +++ b/dbMySQL/create_MySQL_db.sql @@ -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'; diff --git a/dbMySQL/dataLogger_MySQL.py b/dbMySQL/dataLogger_MySQL.py new file mode 100644 index 0000000..fc52adc --- /dev/null +++ b/dbMySQL/dataLogger_MySQL.py @@ -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() diff --git a/mysql_cfg.pickle b/dbMySQL/mysql_cfg.pickle similarity index 100% rename from mysql_cfg.pickle rename to dbMySQL/mysql_cfg.pickle diff --git a/dbMySQL/readConfig_MySQL.py b/dbMySQL/readConfig_MySQL.py new file mode 100644 index 0000000..7c04f0c --- /dev/null +++ b/dbMySQL/readConfig_MySQL.py @@ -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 diff --git a/SQLite/create_SQLite_db.sql b/dbSQLite/create_SQLite_db.sql similarity index 99% rename from SQLite/create_SQLite_db.sql rename to dbSQLite/create_SQLite_db.sql index 1104756..4113002 100644 --- a/SQLite/create_SQLite_db.sql +++ b/dbSQLite/create_SQLite_db.sql @@ -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'); diff --git a/dataLogger_SQLite.py b/dbSQLite/dataLogger_SQLite.py similarity index 88% rename from dataLogger_SQLite.py rename to dbSQLite/dataLogger_SQLite.py index e0c97e8..73d0eb1 100644 --- a/dataLogger_SQLite.py +++ b/dbSQLite/dataLogger_SQLite.py @@ -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") ############## diff --git a/dbSQLite/readConfig_SQLite.py b/dbSQLite/readConfig_SQLite.py new file mode 100644 index 0000000..bd966d7 --- /dev/null +++ b/dbSQLite/readConfig_SQLite.py @@ -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 diff --git a/SQLite/getTodaysTotals.py b/getTodaysTotals.py similarity index 75% rename from SQLite/getTodaysTotals.py rename to getTodaysTotals.py index 15b831c..0ed4414 100644 --- a/SQLite/getTodaysTotals.py +++ b/getTodaysTotals.py @@ -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 diff --git a/SQLite/readTag.py b/readTag.py similarity index 50% rename from SQLite/readTag.py rename to readTag.py index 012fded..b059092 100644 --- a/SQLite/readTag.py +++ b/readTag.py @@ -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]) diff --git a/restorePLC.py b/restorePLC.py index e59d665..bf0a789 100644 --- a/restorePLC.py +++ b/restorePLC.py @@ -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 "-------------------------" diff --git a/setdb_MySQL.sh b/setdb_MySQL.sh new file mode 100644 index 0000000..50ce53e --- /dev/null +++ b/setdb_MySQL.sh @@ -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!" diff --git a/setdb_SQLite.sh b/setdb_SQLite.sh new file mode 100644 index 0000000..d97572b --- /dev/null +++ b/setdb_SQLite.sh @@ -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!" diff --git a/tagSetup.sql b/tagSetup.sql index e74fda4..aebca49 100644 --- a/tagSetup.sql +++ b/tagSetup.sql @@ -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'); diff --git a/SQLite/writeTag.py b/writeTag.py similarity index 77% rename from SQLite/writeTag.py rename to writeTag.py index af151f5..9f2bcea 100644 --- a/SQLite/writeTag.py +++ b/writeTag.py @@ -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)