* 'master' of http://bitbucket.poconsole.net/git/POCONSOLE/datalogger:
  Tested and completed SQLite datalogger using PyComm
  "datalogger_SQLite_Pycomm.py" mostly complete. Needs testing
This commit is contained in:
Patrick McDonagh
2016-03-23 10:04:46 -05:00
4 changed files with 980 additions and 10 deletions

115
create_SQLite_db.sql Normal file
View File

@@ -0,0 +1,115 @@
CREATE TABLE IF NOT EXISTS Event_List (
id INTEGER PRIMARY KEY,
device_name TEXT,
type TEXT,
cond TEXT,
value REAL,
datetime TIMESTAMP,
tag TEXT,
stroke_number INTEGER
);
CREATE TABLE IF NOT EXISTS Hist_Day (
id INTEGER PRIMARY KEY,
gauge_date TIMESTAMP,
percent_run REAL,
kWh REAL,
kWh_regen REAL,
electricity_cost REAL,
peak_load REAL,
min_load REAL,
average_SPM REAL,
production_calculated REAL,
full_card_production REAL,
polished_rod_HP REAL,
lifting_cost REAL,
fluid_above_pump REAL,
pump_intake_pressure REAL,
inflow_rate REAL
);
CREATE TABLE IF NOT EXISTS Well_Test (
id INTEGER PRIMARY KEY,
test_date TIMESTAMP,
test_volume_oil REAL,
test_volume_water REAL,
test_volume_gas REAL,
k_factor REAL,
projected_volume_oil REAL,
projected_volume_water REAL,
api_gravity_oil REAL,
sg_oil REAL,
sg_water REAL,
test_hours REAL
);
CREATE TABLE IF NOT EXISTS config (
id INTEGER PRIMARY KEY,
device_type TEXT,
ip_address TEXT,
dateChanged TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS Notes (
id INTEGER PRIMARY KEY,
author TEXT,
note TEXT,
datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
type INTEGER,
associated_stroke INTEGER,
deleted INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS note_types(
id INTEGER PRIMARY KEY,
type TEXT,
deleted INTEGER DEFAULT 0
);
INSERT INTO note_types (id, type) VALUES ('1', 'Downtime Explanation');
INSERT INTO note_types (id, type) VALUES ('2', 'Configuration Change');
INSERT INTO note_types (id, type) VALUES ('3', 'Info');
INSERT INTO note_types (id, type) VALUES ('4', 'Other');
CREATE TABLE IF NOT EXISTS fluid_shot(
id INTEGER PRIMARY KEY,
shot_datetime TIMESTAMP,
pump_intake_pressure REAL,
fluid_gradient REAL,
friction REAL
);
CREATE TABLE IF NOT EXISTS card_history(
id INTEGER PRIMARY KEY,
Stroke_Time TIMESTAMP,
Card_ID INTEGER,
Card_Type TEXT,
Surface_Position BLOB,
Surface_Load BLOB,
Downhole_Position BLOB,
Downhole_Load BLOB
);
CREATE TABLE IF NOT EXISTS card_history_dates(
id INTEGER PRIMARY KEY,
year INTEGER,
month INTEGER,
day INTEGER,
first_id INTEGER
);
CREATE TABLE IF NOT EXISTS tag_vals(
id INTEGER PRIMARY KEY,
dtime TIMESTAMP,
name TEXT,
val TEXT
);
CREATE TABLE IF NOT EXISTS well_config(
id INTEGER PRIMARY KEY,
tstamp TIMESTAMP,
type TEXT,
val TEXT
);

408
dataLogger_SQLite.py Normal file
View File

@@ -0,0 +1,408 @@
#!/usr/bin/env python
'''
Created on Oct 1, 2014
@author: PJMcdona
'''
import csv
from datetime import datetime
import os
import sys
from random import randint
import time
import sqlite3 as lite
from tuxeip import TuxEIP, LGX, LGX_REAL
# con = lite.connect('test.db')
con = lite.connect("/mnt/usb/welldata.db")
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()
PLC_IP_ADDRESS = "192.168.1.10"
PLC_TYPE = "VFD"
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]
sys.path.append("../")
path_to_CSV = "/mnt/usb/"
# TUXEIP Connection to PLC
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', modeMap[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")))
#############
# 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 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, :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, "
":sp_string, :sl_string, :dp_string, :dl_string)")
with con:
cur = con.cursor()
cur.execute(insert_query, data)
con.commit()
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)
with con:
cur = con.cursor()
# print """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, 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 = 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, 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))
con.commit()
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)
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, v_oil, v_water, v_gas, k_factor, p_v_oil, p_v_water, api_oil, sg_water, test_duration)
# print test_query
storeTest = con.execute(test_query)
con.commit()
already_entered_well_test = True
print "Well Test Stored!"
time.sleep(.20)

429
dataLogger_SQLite_pycomm.py Normal file
View File

@@ -0,0 +1,429 @@
#!/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
con = lite.connect("/mnt/usb/testdata.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:
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:
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':
if (self.last_send_time == 0) or (self.value is None) or not (self.value == v[0]) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend):
self.last_value = self.value
self.value = v[0]
if self.mapFn:
self.value = self.mapFn[v[0]]
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()
# ---------- 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'
}
# ---------- 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)
}
history_tags = {
'run_status': Tag('run_status', 'Pump.Run_Status', 'DINT', 1.0, 3600),
'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}
# }
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)
surf_lod = readArray(PLC_IP_ADDRESS, "Card_Past[1].Surface_Load", num_points + 1)
down_pos = readArray(PLC_IP_ADDRESS, "Card_Past[1].Downhole_Position", num_points + 1)
down_lod = readArray(PLC_IP_ADDRESS, "Card_Past[1].Downhole_Load", num_points + 1)
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:
#############
# 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!"
time.sleep(.20)
if __name__ == '__main__':
main()

View File

@@ -1,20 +1,38 @@
#!/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
from pycomm.ab_comm.clx import Driver as ClxDriver
import logging
def readTag(addr, tag):
'''
Reads tag values from the PLC
addr: IP Address of PLC
tag: tag name (string) or list of tag names (strings)
returns either a tuple with the value and type of the tag or a list of tuples
'''
logging.basicConfig(
filename="u800Driver.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:
err = c.get_status()
c.close()
print err
pass
c.close()
def main():